#! / bin / bash - nie ma takiego pliku ani katalogu


69

Stworzyłem skrypt bash, ale kiedy próbuję go wykonać, dostaję

#!/bin/bash no such file or directory

Muszę uruchomić polecenie: bash script.shaby zadziałało.

Jak mogę to naprawić?


Mam ten problem pod cygwinem, a skrypt, który mógłbym przysiąc, działał już bez problemów. Sprawdziłem wszystkie odpowiedzi, ale żadna nie wydaje się pasować. Inne pytania i odpowiedzi również dotyczyły problemów 32/64-bitowych, ale w przypadku skryptów powłoki można to wykluczyć, prawda?
sty

Znalazłem przyczynę, dodałem szczegóły w nowym anwer unix.stackexchange.com/a/450389/62636 na wypadek, gdyby ktoś również użył #!/usr/bin/env bashzamiast tego #!/bin/bashi szukał tutaj ...
Jan

Odpowiedzi:


100

Ten rodzaj wiadomości zwykle wynika z fałszywej linii shebang, albo dodatkowego powrotu karetki na końcu pierwszej linii, albo BOM na jej początku.

Biegać:

$ head -1 yourscript | od -c

i zobacz jak to się skończy.

To jest źle:

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

To jest poprawne:

0000000   #   !   /   b   i   n   /   b   a   s   h  \n

Użyj dos2unix(lub sed, tr, awk, perl, python...), aby naprawić swój skrypt, czy jest to problem.

Oto jeden, który usunie zarówno BOM, jak i tailing CR:

sed -i '1s/^.*#//;s/\r$//' brokenScript


Pamiętaj, że powłoka używana do uruchomienia skryptu nieznacznie wpłynie na wyświetlane komunikaty o błędach.

Oto trzy skrypty pokazujące tylko swoją nazwę ( echo $0) i posiadające następujące odpowiednie linie shebang:

poprawny skrypt:

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 w ramach 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

Uruchamianie fałszywych przez jawne wywołanie interpretera pozwala na uruchomienie skryptu CRLF bez żadnych problemów:

$ bash ./scriptWithCRLF
./scriptWithCRLF
$ bash ./scriptWithBom
./scriptWithBom: line 1: #!/bin/bash: No such file or directory
./scriptWithBom

Oto zachowanie zaobserwowane w 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 poniżej dash:

$ ./scriptWithCRLF
dash: 2: ./scriptWithCRLF: not found
$ ./scriptWithBom
./scriptWithBom: 1: ./scriptWithBom: #!/bin/bash: not found
./scriptWithBom

2
Innym sposobem ujawnienia, czy taki jest problem, jest hexdump -C yourscript | head -n 1. Nadal bym tego użył, dos2unix yourscriptaby to naprawić.
Kevin M,

Tak, może to być bardzo. Edytowałem w systemie Windows. Rzeczy na wskazówkę.
Nicolas de Fontenay,

1
Gdyby to był problem CRLF, nie zobaczyłby się #!/bin/bash no such file or directorykomunikatu o błędzie, ponieważ nie ma powodu, aby cokolwiek próbowało się uruchomić lub otworzyć #!/bin/bash. To, /bin/bash<CR>co zostanie wykonane.
Stéphane Chazelas

1
@StephaneChazelas Ponieważ dos2unix naprawił problem, nie ma wątpliwości, że nie był to problem CRLF. Komunikat o błędzie prawdopodobnie został właśnie niedokładnie zapisany.
Jlliagre

6
dos2unixusuwa również BOM UTF-8. LM UTF-8 mógł wyjaśnić komunikat o błędzie.
Stéphane Chazelas


9

Właściwie właściwy shebang dla skryptu bash jest następujący:

#!/usr/bin/env bash

Ponieważ w FreeBSD bash znajduje się w /usr/local/bin/bash


13
W takich przypadkach „właściwe” jest trudnym słowem. Być może lepszym wyrażeniem byłoby „mniej podatne na błędy”.
HalosGhost

1
To też jest okropne; założenie, że istnieje / usr, jest złe IMO. Na przykład Haiku nie ma / usr.
jessicah

9

Możesz użyć vi, aby naprawić oba problemy, jeśli istnieją:

vi <your_file>
:set ff=unix
:set nobomb
:wq

Odpowiedzi powinny być jak najbardziej samodzielne. Pytanie nie wspomina o dwóch problemach; jeśli zamierzasz skorzystać z innych odpowiedzi, powinieneś przynajmniej powiedzieć, jakie są. Jeszcze lepiej, powinieneś wyjaśnić, jak to odpowiada na pytanie.
G-Man

Bardzo szybka naprawa bez pobierania dodatkowych narzędzi systemu Windows, dzięki!
steampowered

1
@ G-Man Inne odpowiedzi już o tym wspominają o wiele bardziej szczegółowo, niż chciałbym się zajmować. Nie trzeba powtarzać, ale jeśli nie jest to boleśnie oczywiste, możesz mieć końcówkę linii Windows i ukryty znak BOM systemu Windows. Myślę, że wiele osób, które skanują odpowiedzi, docenia zwięzłość zamiast być samowystarczalnym, szczególnie gdy w innych odpowiedziach jest znacznie więcej szczegółów.
cwash

4

Jeśli nie masz dos2unix, jest to sposób na rozwiązanie tego problemu.

cp script _p4 && tr -d '\r' < _p4 > script && rm _p4

3

Znak kolejności bajtów (BOM)

Może to być spowodowane przez BOM. Z Wikipedii BOM to

Znak kolejności bajtów (BOM) to znak Unicode, znak kolejności bajtów U + FEFF (BOM), którego pojawienie się jako magicznej liczby na początku strumienia tekstowego może sygnalizować kilka rzeczy programowi używającemu tekstu

Niestety, nic nie sygnalizuje jądru Linuksa, który obsługuje linię she-bang. Możesz sprawdzić, czy masz BOM, używając file,

file /tmp/foo 
/tmp/foo: UTF-8 Unicode (with BOM) text

Możesz też zrzucić hex pierwszych kilka znaków i sprawdzić, czy pasują one do któregokolwiek ze znaków BOM ręcznie

Możesz rozebrać znaki BOM, gdy już je znasz,

sed -i '1 s/^\xef\xbb\xbf//' *.txt

0

Miałem problem przez przypadkowe dodanie niewłaściwego pliku wykonywalnego bash do PATHi ponieważ w moim skrypcie zastosowano bardziej elastyczny #!/usr/bin/env bashshebang (pobierz pierwszy plik wykonywalny bash ze ścieżki).

command -v bash
/cygdrive/c/Program Files/Git/bin//bash

Zainstalowałem GIT dla Windows, aby współpracował cygwinz GUI Windows GIT (nie działał z natywnym gitem Cygwina ...). Rozwiązałem to teraz, przechodząc na #!/bin/bashsheband i usuwając GIT dla Windows z PATH.


-3

Próbować #!/bin/bash

Druga rzecz: find / -name bash
trzecia rzecz:ls -al /bin/bash


Lub po prostu which bash. Wiemy, że to znajduje, ponieważ współpracuje bash script.sh.
Kevin

Prawdziwe. Jak już wspomniano, istnieje znacznie bardziej przenośna metoda / usr / bin / env, aby program zlokalizował bash (lub inny interpreter) dla Ciebie. Nie trzeba kodować pah na stałe.
Hennes,
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.