linia shebang nie działa z cr-lf


10

Dlaczego nie działają fragmenty następujących skryptu elementarnego:

$ cat hello.sh
#! /bin/sh
echo Hello
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory

$ cat hello.py
#! /usr/bin/env python3
print("Hello")
$ ./hello.py
: No such file or directory

podczas gdy ręczne wywoływanie tłumacza działa:

$ sh hello.sh
Hello
$ python3 hello.py
Hello

Odpowiedzi:


11

Twoje skrypty prawdopodobnie mają zakończenia linii CR-LF w stylu DOS, a nie zakończenia linii LF w stylu uniksowym. ^ M widoczny w komunikacie o błędzie w pierwszym przypadku oznacza, że ​​znak 0D został zinterpretowany jako część nazwy interpretera skryptu, a nie jako część zakończenia linii (jak można się spodziewać). Ponieważ w systemie nie ma pliku wykonywalnego ze ścieżką zawierającą znak 0D (^ M), system nie jest w stanie wywołać interpretera. Po ręcznym wywołaniu interpretera jest on w stanie obsłużyć oba rodzaje zakończeń linii obecnych w skrypcie.

Jeśli konwertujesz skrypty na użycie zakończeń linii LF w stylu uniksowym, powinieneś zobaczyć, jak działa shebang. Czytaj dalej, aby zobaczyć ilustrację.

W poniższej sesji todos i fromdos to narzędzie (dostępne w Ubuntu jako pakiet tofrodos) do konwersji konwencji zakończenia linii z CR-LF na LF. Wszelkie równoważne narzędzie (patrz to pytanie unix.SE ) zrobiłoby to w celu demonstracji.

Poniższy zapis sesji (wykonywany przy użyciu tych samych plików skryptów) powinien wyjaśnić sytuację:

$ fromdos hello.sh
$ ./hello.sh
Hello
$ todos hello.sh
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory
$
$ fromdos hello.py
$ ./hello.py
Hello
$ todos hello.py
$ ./hello.py
: No such file or directory
$

To wydaje się , że jest to kernel, który odczytuje linię shebang i najwyraźniej jądro Linux (przynajmniej w wersji na moim systemie Kubuntu Saucy) nie rozpoznaje CR jako część linii CR-LF kończącym konwencję.

Jeśli wydaje się, że shebang skryptu nie działa (tj. Ręczne wywoływanie interpretera na skrypcie działa, ale nie można wykonać skryptu przy użyciu jego nazwy pliku, nawet jeśli już to zrobiłeś chmod +x), jest to możliwy powód.

UWAGA: Podziękowania dla innych, którzy również skomentowali. Z przyjemnością też usłyszę, czy są lepsze odpowiedzi!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.