Belirli bir python kurulumuyla çalıştırılması gereken bir Python betiğim var. Bir shebang yapmak için çalışacak bir yolu var mı $FOO/bar/MyCustomPython
?
Belirli bir python kurulumuyla çalıştırılması gereken bir Python betiğim var. Bir shebang yapmak için çalışacak bir yolu var mı $FOO/bar/MyCustomPython
?
Yanıtlar:
Shebang hattı çok sınırlı. Birçok unix değişkeninde (Linux dahil) sadece iki kelimeniz olabilir: bir komut ve bir argüman. Genellikle bir uzunluk sınırlaması da vardır.
Genel çözüm küçük bir kabuk ambalajı yazmaktır. Python komut dosyasını adlandırın foo.py
ve kabuk komut dosyasını yanına koyun foo.py
ve çağırın foo
. Bu yaklaşım Python betiğinde herhangi bir başlık gerektirmez.
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
Bir başka cazip yaklaşım, yukarıdaki gibi bir sarmalayıcı komut dosyası yazmak #!/path/to/wrapper/script
ve Python komut dosyasına shebang satırı olarak koymaktır . Ancak, çoğu sendika shebang scriptlerinin zincirlenmesini desteklemiyor, bu yüzden bu işe yaramayacak.
Eğer MyCustomPython
idi $PATH
şunu kullanabilirsiniz env
bana arama:
#!/usr/bin/env MyCustomPython
import …
Yine bir başka yaklaşım, betiğin hem geçerli bir kabuk betiği (kendi başına doğru Python yorumlayıcısını yükleyen) hem de hedef dilde geçerli bir betiği (burada Python) ayarlamasıdır. Bu, hedef diliniz için böyle bir çift dilli komut dosyası yazmanın bir yolunu bulmanızı gerektirir. Perl'de buna bilinir if $running_under_some_shell
.
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
Python'da da aynı etkiyi elde etmenin bir yolu. Kabuğunda, "true"
bir true
argümanları (iki adet tek karakter dizileri göz ardı programı :
ve '
) ve gerçek değer geri gönderir. Python'da, "true"
bir boolean olarak yorumlandığında doğru olan bir dizedir, bu yüzden bu if
her zaman doğru olan ve bir string değişmezini yürüten bir komuttur.
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
Rosetta kodunda, başka dillerde de böyle çift dilli komut dosyaları bulunur.
PYTHONPATH
, kök erişimim olmayan bir sistemdeki CGI betiği için standart olmayan bir konumdan modülleri yüklemek üzere env değişkenini düzenlemek için kullandım. Hayat kurtarıcı. Tekrar teşekkürler.
Shebang satırları değişken genişlemeden geçmez, bu yüzden $FOO/MyCustomPython
dollar-FOO -... adında bir yürütülebilir dosyayı arayacağı gibi kullanamazsınız .
Alternatif olarak, Shebang'ınızın tercüman olarak bir kabuk betiğine işaret etmesini sağlamaktır ve bu kabuk betiği daha sonra doğru besini bulmak ve yürütmek için ortam değişkenlerini kullanabilir.
Örnek: Aşağıdaki içeriğe sahip bir mypython.sh
komut dosyası oluşturun /usr/local/bin
(veya üzerinizdeki başka bir dizin $PATH
):
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
o zaman bir Python komut aracılığıyla yürütülecek olması bu mesele satırını kullanabilirsiniz MyCustomPython
yoluyla mypython.sh
:
#!/usr/bin/env mypython.sh
$python
, $PYTHON
kurallara göre, ortam değişkenlerini (PAGER, EDITOR, SHELL ... $PYTHON
komut dosyanızdaki bir ortam değişkeni değil) ve iç kabuk değişkenlerini (BASH_VERSION, RANDOM, ...) büyük harflerle yazıyoruz. Diğer tüm değişken isimleri en az bir küçük harf içermelidir. Bu sözleşme, çevresel ve dahili değişkenleri yanlışlıkla geçersiz kılmayı önler. Ayrıca, komut dosyalarınız için uzantıları kullanmayın. Komut dosyaları, çalıştırabileceğiniz yeni komutları tanımlar ve komutlara genellikle uzantı verilmez.
Özel python kurulumunun mutlak yolunu kullanabilir ya da içine koyabilir $PATH
ve kullanabilirsiniz #!/usr/bin/env [command]
. Aksi takdirde, bunun için bir sarmalayıcı yazın ve exec
örnek olarak işlem görüntüsünü değiştirmek için kullanın :
#!/bin/bash
exec "$ENV/python" "$@"
Öncelikle, Python sürümünüzün halihazırda kurulu olan standart Python'dan (örneğin, ek bir modül) ne kadar farklı olduğunu ve ardından 'switch' programının başında Python'un nasıl adlandırıldığını belirleyin:
#!/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
Bu, programın başka herhangi bir Python örneği tarafından çağrılmasına izin vermelidir. Sistemin pythonunda modül olarak alınamayan yerleşik sql kütüphanesine sahip bir örnek için benzer bir şey yapıyorum.
Somut yol seçenekleriyle değiştirebiliyorsanız $FOO
, doğrudan bir özel ayar $FOO/bar/MyCustomPython
yaparak env
shebang hattına özel Python sürümünüzü nerede arayacağınızı PATH
söyleyebilirsiniz.
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
Düzenleme : Yalnızca PATH değeri ataması etrafındaki tırnak işaretleri olmadan çalışıyor gibi görünüyor:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
PATH
Böyle daha iyi genişletmek :PATH=$PATH:/path/to/whatever...