2012-07-03 9 views
8

bin/env mam ten problem!

System A działa Ubuntu i potrzebuje Python 2.6 na kilka różnych rzeczy.
Zainstalowałem osobno Python 2.7 oddzielnie System A
System B ma natywnie.
czynienia z wieloma wersjami plików python python gdy trzeba użyć #/python

Mam skrypt python BLAH, który mówi #!/bin/env python do góry.
W dalszej kolejności wykonuje inny skrypt SIGH, który na górze również mówi: #!/bin/env python.

BLAH musi działać na obu System A lub System B i zawsze musi uruchomić Python 2.7

----
częścią mojego rozwiązania tej pory:
mieć skrypt otoki, który próbuje najpierw zobaczyć jeśli which python wskazuje na Python 2.7
Jeśli to jest w porządku, uruchom BLAH z tą ścieżką dla Pythona.
Spróbuj ponownie which python2.7 i użyj tej ścieżki do uruchomienia BLAH i dodaj tę ścieżkę do env PATH.

Problem z tym rozwiązaniem jest:

Na System A (która Python 2.7 zainstalowane oddzielnie)
Kiedy BLAH Wykonuje, biegnie z Pythona 2.7 ze względu na skrypcie otoki pisałem (w porządku tak daleko ..)
Kiedy BLAH ikra SIGH, SIGH używa shebang znaleźć Pythona w ścieżce i wtedy jest w tarapatach, ponieważ szuka pytona w env „s PATH i powinno być patrząc na python2.7 w ścieżce.

Czy istnieje czysty sposób radzenia sobie z tym problemem?

Z góry dziękuję!

+0

Czy można zaimportować, a następnie uruchomić SIGH z BLAH? –

+0

Nie jestem pewien, czy musisz dodać ścieżkę, którą uzyskasz z 'co' do' PATH' - 'który' faktycznie będzie tylko wyszukiwał ścieżki zawarte w 'PATH'. – jedwards

Odpowiedz

9

Jeśli masz skrypt, który potrzebuje pewnej wersji Pythona, na przykład 2,7, chciałbym zmienić pierwszą linię

#!/bin/env python2.7 

a następnie upewnij się, że python2.7 jest na swojej drodze (może trzeba dodać w razie potrzeby dowiązania symboliczne). We wszystkich dystrybucjach, z których korzystałem, te dowiązania symboliczne już istnieją.

(W rzeczywistości, python jest zwykle dowiązaniem do pythonX który jest dowiązaniem do pythonX.Y lub, w moim przypadku, python -> python2 -> python2.7.)

Nie ma potrzeby, aby twardym kodu pełnej ścieżki, jak to może się różnić od distro do distro lub box to box.

Ale ponieważ nie powinno być żadnych dwuznaczności dla pliku wykonywalnego na swojej drodze nazwie python2.7, powinno być w porządku, bez konieczności martwienia się o ścieżki ciężko kodowania.

Alternatywnie, z poziomu pierwszego skryptu, można wywołać interpreter Pythona bezpośrednio, jak w:

subprocess.Popen(['pythonX.Y', SCRIPT_NAME]) 

zamiast

subprocess.Popen([SCRIPT_NAME]) 

EDIT Jak JF Sebastian zauważa w komentarzach, możesz użyć sys.executable w pierwszym argumencie, aby upewnić się, że drugi skrypt został przekazany do tego samego interpretera, co pierwszy. np

subprocess.Popen([sys.executable, SCRIPT_NAME]) 

Na marginesie, które mogą lub nie mogą być przydatne, można uzyskać dostęp do wersji „aktualnej” interpreter Pythona wewnątrz skryptu przez

import sys 
print(sys.hexversion) 

, które mogą być użyteczne aby ustalić, czy działa poprawny interpreter.

+0

@jedwards pewien shebang, dla którego nie działa, otrzymywanie nieprawidłowego błędu ścieżki w apache – Volatil3

3

Co zrobić, to najpierw zmienić ścieżkę #!/bin/env na ścieżkę python2.7 bezpośrednio, na przykład: #!/usr/local/bin/python2.7 będzie działać.

W przypadku systemu A i B ścieżce python2.7 znajdują się w różnych miejscach (co wydaje się być sprawa) zawsze można utworzyć dowiązania takiego:

ln -s /bin/python2.7 /usr/local/bin/python2.7 

i powinien działać dobrze.

2

Dlaczego nie używać virtualenv? To pozwala na użycie dowolnej wersji Pythona zainstalowany (oprócz innych rzeczy) ...

starenka /tmp % virtualenv test -ppython2.6 
Running virtualenv with interpreter /usr/bin/python2.6 
New python executable in test/bin/python2.6 
Also creating executable in test/bin/python 
Installing setuptools............................done. 
Installing pip...............done. 

starenka /tmp % source test/bin/activate 

(test)starenka /tmp % which python 
/tmp/test/bin/python 

(test)starenka /tmp % python --version 
Python 2.6.8 

(test)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test/test.py 

(test)starenka /tmp % chmod +x test/test.py 

(test)starenka /tmp % test/test.py 
(2, 6, 8, 'final', 0) 

starenka /tmp % virtualenv test7 -ppython2.7 
Running virtualenv with interpreter /usr/bin/python2.7 
New python executable in test7/bin/python2.7 
Also creating executable in test7/bin/python 
Installing setuptools............done. 
Installing pip...............done. 
starenka /tmp % source test7/bin/activate 

(test7)starenka /tmp % which python 
/tmp/test7/bin/python 

(test7)starenka /tmp % python --version 
Python 2.7.3rc2 

(test7)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test7/test.py 

(test7)starenka /tmp % chmod +x test7/test.py 

(test7)starenka /tmp % test7/test.py 
sys.version_info(major=2, minor=7, micro=3, releaselevel='candidate', serial=2) 
0

głupie i proste

w powłoce, jeśli to konieczne:

ln -s /path/to/your/python2.X /usr/local/bin/python2 

W Pythonie scenariusz:

#!/bin/bash 
"exec" "python2" "$0" 

byłem przez tego rodzaju pro usterki, a to rozwiązanie rozwiązało większość przypadków i było łatwo przenoszone z jednego systemu do drugiego (można napotkać różne ścieżki między systemami, różne wersje oprogramowania ...). Najpierw utwórz dowiązanie symboliczne, aby upewnić się, że uruchomisz odpowiednią wersję Pythona (jest to szczególnie prawdziwe teraz, gdy nigdy nie masz teraz, jeśli Python3 jest po prostu Pythonem), a następnie polegaj na bash env. Tak więc nie zmieniasz swojego skryptu za każdym razem, gdy celujesz w system dla skryptu util, który nie wymaga kłopotów z pakietem.