Saya memiliki skrip Python yang harus dijalankan dengan instalasi python tertentu. Apakah ada cara untuk membuat shebang agar bisa berjalan $FOO/bar/MyCustomPython
?
Saya memiliki skrip Python yang harus dijalankan dengan instalasi python tertentu. Apakah ada cara untuk membuat shebang agar bisa berjalan $FOO/bar/MyCustomPython
?
Jawaban:
Garis shebang sangat terbatas. Di bawah banyak varian unix (termasuk Linux), Anda hanya dapat memiliki dua kata: perintah dan satu argumen. Sering juga ada batasan panjang.
Solusi umum adalah dengan menulis pembungkus shell kecil. Beri nama skrip Python foo.py
, dan letakkan skrip shell di sebelahnya foo.py
dan panggil foo
. Pendekatan ini tidak memerlukan header tertentu pada skrip Python.
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
Pendekatan lain yang menggoda adalah menulis skrip wrapper seperti yang ada di atas, dan meletakkannya #!/path/to/wrapper/script
sebagai garis shebang pada skrip Python. Namun, sebagian besar unices tidak mendukung perangkaian skrip shebang, jadi ini tidak akan berhasil.
Jika MyCustomPython
ada di $PATH
, Anda dapat menggunakannya env
untuk mencarinya:
#!/usr/bin/env MyCustomPython
import …
Namun pendekatan lain adalah mengatur agar skrip menjadi skrip shell yang valid (yang memuat penerjemah Python yang tepat pada dirinya sendiri) dan skrip yang valid dalam bahasa target (di sini Python). Ini mengharuskan Anda menemukan cara untuk menulis skrip dua bahasa untuk bahasa target Anda. Dalam Perl, ini dikenal sebagai if $running_under_some_shell
.
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
Inilah salah satu cara untuk mencapai efek yang sama dengan Python. Dalam shell, "true"
adalah true
utilitas, yang mengabaikan argumennya (dua string karakter tunggal :
dan '
) dan mengembalikan nilai sebenarnya. Dalam Python, "true"
adalah string yang benar ketika diartikan sebagai boolean, jadi ini adalah if
instruksi yang selalu benar dan mengeksekusi string literal.
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
Kode Rosetta memiliki skrip dua bahasa seperti itu dalam beberapa bahasa lain.
PYTHONPATH
variabel env untuk memuat modul dari lokasi non-standar untuk skrip CGI pada sistem saya tidak memiliki akses root. Penolong. Terima kasih lagi.
Baris Shebang tidak mengalami ekspansi variabel, jadi Anda tidak dapat menggunakan $FOO/MyCustomPython
karena akan mencari executable bernama dollar-FOO -...
Alternatifnya adalah memiliki titik shebang Anda ke skrip shell sebagai penerjemah, dan skrip shell ini kemudian dapat menggunakan variabel lingkungan untuk menemukan yang benar dan mengeksekusinya.
Contoh: buat mypython.sh
skrip di /usr/local/bin
(atau direktori lain di Anda $PATH
), dengan konten berikut:
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
maka Anda dapat menggunakan baris shebang ini untuk menjalankan skrip Python MyCustomPython
melalui mypython.sh
:
#!/usr/bin/env mypython.sh
$python
, bukan $PYTHON
- berdasarkan konvensi, kami mengkapitalkan variabel lingkungan (PAGER, EDITOR, SHELL ... $PYTHON
dalam skrip Anda bukan variabel lingkungan) dan variabel shell internal (BASH_VERSION, RANDOM, ...). Semua nama variabel lainnya harus mengandung setidaknya satu huruf kecil. Konvensi ini menghindari variabel lingkungan dan internal yang secara tidak sengaja diabaikan. Selain itu, jangan gunakan ekstensi untuk skrip Anda. Script mendefinisikan perintah baru yang dapat Anda jalankan, dan perintah umumnya tidak diberikan ekstensi.
Anda bisa menggunakan jalur absolut ke instalasi python khusus, atau Anda bisa memasukkannya ke dalam $PATH
dan menggunakan Anda #!/usr/bin/env [command]
. Kalau tidak, tulis pembungkus untuk itu dan gunakan exec
untuk mengganti gambar proses, sebagai contoh:
#!/bin/bash
exec "$ENV/python" "$@"
Pertama, tentukan bagaimana versi Python Anda berbeda dari Python standar yang sudah diinstal (misalnya, modul tambahan) dan kemudian pada awal program 'aktifkan' bagaimana Python disebut:
#!/usr/bin/python
import os
import sys
try:
import MyCustomModule
except ImportError:
# only need to use expandvar if you know the string below has an envvar
custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
os.execv(custprog, sys.argv) # call alternate python with the same arguments
raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter
Ini harus memungkinkan program dipanggil oleh instance Python lainnya. Saya melakukan sesuatu yang mirip untuk contoh dengan built-in sql library yang tidak dapat diimpor sebagai modul di python sistem.
Jika Anda dapat mengganti $FOO
di $FOO/bar/MyCustomPython
dengan pilihan jalan beton, Anda dapat memberitahu env
garis peristiwa di mana untuk mencari kustom versi Python Anda dengan langsung menetapkan kustom PATH
di dalamnya.
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
Sunting : Tampaknya hanya berfungsi tanpa tanda kutip di sekitar penetapan nilai PATH:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
PATH
seperti ini:PATH=$PATH:/path/to/whatever...