Jestem w interesującej sytuacji, w której mam skrypt w języku Python, który teoretycznie może być uruchamiany przez różnych użytkowników w różnych środowiskach (i PATH) i na różnych systemach Linux. Chcę, aby ten skrypt był wykonywalny na tak wielu z nich, jak to możliwe bez sztucznych ograniczeń. Oto niektóre znane konfiguracje:
- Python 2.6 jest systemową wersją Pythona, więc wszystkie python, python2 i python2.6 istnieją w katalogu / usr / bin (i są równoważne).
- Python 2.6 to systemowa wersja Python, jak wyżej, ale Python 2.7 jest instalowany obok niego jako python2.7.
- Python 2.4 to systemowa wersja Python, której mój skrypt nie obsługuje. W / usr / bin mamy python, python2 i python2.4, które są równoważne, i python2.5, które obsługuje skrypt.
Chcę uruchomić ten sam wykonywalny skrypt Pythona na wszystkich trzech z nich. Byłoby miło, gdyby najpierw próbował użyć /usr/bin/python2.7, jeśli istnieje, to wróć do /usr/bin/python2.6, a następnie wróć do /usr/bin/python2.5, a następnie po prostu pomiń błąd, jeśli żaden z nich nie był obecny. Nie jestem jednak zbytnio rozłączony przy użyciu najnowszej możliwej wersji 2.x, pod warunkiem, że jest w stanie znaleźć jednego z poprawnych tłumaczy, jeśli jest obecny.
Moją pierwszą skłonnością była zmiana linii shebang z:
#!/usr/bin/python
do
#!/usr/bin/python2.[5-7]
ponieważ działa to dobrze w bash. Ale uruchomienie skryptu daje:
/usr/bin/python2.[5-7]: bad interpreter: No such file or directory
Okej, więc wypróbowuję następujące, które działa również w bash:
#!/bin/bash -c /usr/bin/python2.[5-7]
Ale znowu to się nie udaje w przypadku:
/bin/bash: - : invalid option
Okay, oczywiście mógłbym napisać osobny skrypt powłoki, który znajdzie właściwy interpreter i uruchomi skrypt Pythona za pomocą dowolnego znalezionego interpretera. Po prostu uważam za kłopot z dystrybucją dwóch plików, w których jeden powinien wystarczyć, pod warunkiem, że jest uruchomiony z zainstalowanym najnowszym interpreterem języka Python 2. Poproszenie ludzi o jawne wywołanie tłumacza (np. $ python2.5 script.py
) Nie wchodzi w grę. Poleganie na skonfigurowaniu PATH użytkownika w określony sposób również nie jest opcją.
Edytować:
Sprawdzanie wersji w skrypcie Python nie będzie działać, ponieważ używam instrukcji „z”, która istnieje od wersji Python 2.6 (i może być używana w wersji 2.5 z from __future__ import with_statement
). Powoduje to, że skrypt natychmiast kończy się niepowodzeniem z nieprzyjaznym dla użytkownika błędem SyntaxError i uniemożliwia mi kiedykolwiek sprawdzenie najpierw wersji i wygenerowanie odpowiedniego błędu.
Przykład: (spróbuj tego z interpreterem języka Python mniejszym niż 2.6)
#!/usr/bin/env python
import sys
print "You'll never see this!"
sys.exit()
with open('/dev/null', 'w') as out:
out.write('something')
./script.py
) Spowodowałoby wykonanie go przez python2.4, co spowodowałoby, że kod wykryłby, że jest to niewłaściwa wersja (i prawdopodobnie,). Ale istnieje doskonale dobry python2.5, który mógłby zostać użyty jako interpreter!
exec
jeśli tak, w przeciwnym razie wydrukuj błąd.
execve
). Argumenty to literały łańcuchowe, brak globowania, brak wyrażeń regularnych. Otóż to. Nawet jeśli pierwszy argument to „/ bin / bash”, a drugie opcje („-c ...”), te opcje nie są analizowane przez powłokę. Są one przekazywane bez przetworzenia do pliku wykonywalnego bash, dlatego otrzymujesz te błędy. Dodatkowo shebang działa tylko wtedy, gdy jest na początku. Obawiam się, że nie masz szczęścia (brakuje skryptu, który znajduje interpreter języka Python i podaje go TUTAJ, co brzmi jak okropny bałagan).
import sys; sys.version_info()
aby sprawdzić, czy użytkownik ma wymaganą wersję Pythona.