Utworzyłem skrypt bash, ale kiedy próbuję go wykonać, otrzymuję
#!/bin/bash no such file or directory
Muszę uruchomić polecenie: bash script.sh
, aby zadziałało.
Jak mogę naprawić to?
Komentarze
Odpowiedź
Ten rodzaj wiadomości jest zwykle spowodowany fałszywa linia shebang, albo dodatkowy powrót karetki na końcu jodły wiersz lub BOM na jego początku.
Uruchom:
$ head -1 yourscript | od -c
i zobacz, jak się skończy.
To jest złe:
0000000 # ! / b i n / b a s h \r \n
To też jest złe:
0000000 357 273 277 # ! / b i n / b a s h \n
Wszystko się zgadza:
0000000 # ! / b i n / b a s h \n
Użyj dos2unix
(lub sed
, tr
, awk
, perl
, python
…), aby naprawić skrypt, jeśli na tym polega problem.
Oto jeden, który usunie zarówno zestawienie komponentów, jak i uzupełniające CR:
sed -i "1s/^.*#//;s/\r$//" brokenScript
Zauważ, że powłoka, której używasz do uruchomienia skryptu, nieznacznie wpłynie na wyświetlane komunikaty o błędach.
Oto trzy skrypty pokazujące tylko ich nazwę (echo $0
) i mające następujące odpowiednie wiersze shebang:
correctScript:
0000000 # ! / b i n / b a s h \n
scriptWithBom:
0000000 357 273 277 # ! / b i n / b a s h \n
scriptWithCRLF:
0000000 # ! / b i n / b a s h \r \n
Uruchomienie ich pod bash spowoduje wyświetlenie następujących komunikatów:
$ ./correctScript ./correctScript $ ./scriptWithCRLF bash: ./scriptWithCRLF: /bin/bash^M: bad interpreter: No such file or directory $ ./scriptWithBom ./scriptWithBom: line 1: #!/bin/bash: No such file or directory ./scriptWithBom
Uruchomienie pliku bo gus przez jawne wywołanie interpretera umożliwia uruchomienie skryptu CRLF bez żadnego problemu:
$ bash ./scriptWithCRLF ./scriptWithCRLF $ bash ./scriptWithBom ./scriptWithBom: line 1: #!/bin/bash: No such file or directory ./scriptWithBom
Oto zachowanie obserwowane pod ksh
:
$ ./scriptWithCRLF ksh: ./scriptWithCRLF: not found [No such file or directory] $ ./scriptWithBom ./scriptWithBom[1]: #!/bin/bash: not found [No such file or directory] ./scriptWithBom
i pod dash
:
$ ./scriptWithCRLF dash: 2: ./scriptWithCRLF: not found $ ./scriptWithBom ./scriptWithBom: 1: ./scriptWithBom: #!/bin/bash: not found ./scriptWithBom
Komentarze
- Innym sposobem na ujawnienie, czy to jest problem, jest
hexdump -C yourscript | head -n 1
. Nadal użyłbymdos2unix yourscript
, aby to naprawić. - Gdyby był to problem z CRLF, nie ' nie zobaczysz
#!/bin/bash no such file or directory
komunikat o błędzie, ponieważ ' nie ma powodu, aby cokolwiek próbowało wykonać lub otworzyć#!/bin/bash
. To ' s/bin/bash<CR>
co zostanie wykonane. - @StephaneChazelas Ponieważ dos2unix rozwiązał problem, nie ma wątpliwości to nie był ' problem z CRLF. Komunikat o błędzie został prawdopodobnie niedokładnie przepisany.
-
dos2unix
usuwa również BOM UTF-8. BOM UTF-8 mógł wyjaśnić komunikat o błędzie. - To smutne, jak niezgodny jest Microsoft. Nawet w przypadku czegoś tak podstawowego jak ASCII.
Odpowiedź
Może to być również spowodowane przez BOM w UTF -8 skrypt. Jeśli tworzysz skrypt w systemie Windows, czasami na początku pliku pojawia się trochę śmieci.
Komentarze
- BOM można łatwo usunąć za pomocą awk, jak w stackoverflow.com/questions/1068650/…
- Zwróć uwagę, że Visual Studio dla Mac wstawi zestawienie komponentów.
Odpowiedź
Właściwie, właściwy shebang dla skryptu bash to:
#!/usr/bin/env bash
Ponieważ w freeBSD bash znajduje się w /usr/local/bin/bash
Komentarze
- ” right ” jest trudnym słowem w takich przypadkach. Być może lepszym wyrażeniem byłoby ” mniej podatne na błędy „.
- To też jest okropne; założenie, że / usr istnieje, jest złym IMO. Na przykład Haiku nie ma / usr.
Odpowiedź
Możesz użyć vi, aby naprawić oba problemy jeśli istnieją:
vi <your_file> :set ff=unix :set nobomb :wq
Komentarze
- Odpowiedzi powinny być możliwie samodzielne. Pytanie nie wspomina o dwóch problemach; jeśli masz zamiar opierać się na innych odpowiedziach, powinieneś przynajmniej powiedzieć, jakie one są. Jeszcze lepiej, powinieneś wyjaśnić, jak to odpowiada na pytanie.
- Bardzo szybka poprawka bez pobierania większej liczby narzędzi systemu Windows, dzięki!
- @ G-Man Inne odpowiedzi już o tym wspominam dużo dokładniej, niż chciałbym się w to zagłębiać.Nie ma potrzeby powtarzania, ale jeśli ' nie jest tak oczywiste, możesz mieć zakończenie wiersza systemu Windows i ukryty znak BOM systemu Windows. Myślę, że wiele osób, które skanują odpowiedzi, docenia zwięzłość zamiast samodzielności, zwłaszcza gdy inne odpowiedzi zawierają dużo więcej szczegółów.
Odpowiedź
Jeśli nie masz dos2unix, jest to sposób na rozwiązanie tego problemu.
cp script _p4 && tr -d "\r" < _p4 > script && rm _p4
Odpowiedź
Znak kolejności bajtów (BOM)
Może to być spowodowane BOM. Z Wikipedii BOM to
Znak kolejności bajtów (BOM) to znak Unicode, U + FEFF znak kolejności bajtów (BOM) , którego pojawienie się jako magiczna liczba na początku strumienia tekstu może sygnalizować programowi, który konsumuje tekst, kilka rzeczy
Niestety, nie sygnalizuje niczego jądru Linuksa, które obsługuje linię she-bang. Możesz sprawdzić, czy masz zestawienie komponentów, używając file
,
file /tmp/foo /tmp/foo: UTF-8 Unicode (with BOM) text
Lub możesz wykonać zrzut heksowy kilka pierwszych znaków i zobacz , jeśli dopasują ręcznie dowolny ze znaków zestawienia komponentów
Znaki zestawienia komponentów można usunąć, gdy już je znasz ,
sed -i "1 s/^\xef\xbb\xbf//" *.txt
Odpowiedź
Miałem problem z przypadkowym dodaniem niewłaściwego basha wykonywalny do PATH
i ponieważ w moim skrypcie użyto bardziej elastycznego #!/usr/bin/env bash
shebang (weź pierwszy plik wykonywalny bash ze ścieżki).
command -v bash /cygdrive/c/Program Files/Git/bin//bash
Zainstalowałem GIT dla Windows do pracy w cygwin
razem z GUI Windows GIT (nie działało z natywnym gitem cygwin …). Rozwiązałem to teraz, przełączając się na #!/bin/bash
sheband i usuwając GIT dla Windows z PATH
.
Odpowiedź
Spróbuj #!/bin/bash
Druga sprawa: find / -name bash
Trzecia sprawa: ls -al /bin/bash
Komentarze
- Lub po prostu
which bash
. Wiemy, że ' znajduje taki, ponieważ ' współpracuje zbash script.sh
. - Prawda. Jak już wspomniano, istnieje znacznie bardziej przenośna metoda / usr / bin / env, dzięki której program lokalizuje bash (lub inny interpreter). Nie ma potrzeby, aby na stałe kodować PaH.
#!/usr/bin/env bash
zamiast#!/bin/bash
i również tutaj …