#! / bin / bash - keine solche Datei oder Verzeichnis

70

Ich habe ein Bash-Skript erstellt, aber wenn ich versuche, es auszuführen, erhalte ich

#!/bin/bash no such file or directory

Ich muss den Befehl ausführen: bash script.shdamit es funktioniert.

Wie kann ich das beheben?

Nicolas de Fontenay
quelle
Ich habe dieses Problem jetzt unter Cygwin mit einem Skript, von dem ich schwören könnte, dass es bereits ohne Probleme ausgeführt wird. Ich habe alle Antworten überprüft, aber keine scheint zu passen. Andere Fragen und Antworten erwähnten auch 32/64-Bit-Probleme, aber für Shell-Skripte könnte dies ausgeschlossen werden, oder?
Januar
Gefunden dem Grund, zusätzliche Details in neuen anwer unix.stackexchange.com/a/450389/62636 falls jemand hat auch verwendet #!/usr/bin/env bashstatt #!/bin/bashund auch auf der Suche hier ...
Januar

Antworten:

100

Diese Art von Nachricht ist normalerweise auf eine falsche Shebang-Zeile zurückzuführen, entweder einen zusätzlichen Wagenrücklauf am Ende der ersten Zeile oder eine Stückliste am Anfang.

Lauf:

$ head -1 yourscript | od -c

und sehen, wie es endet.

Das ist falsch:

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

Das ist auch falsch:

0000000 357 273 277   #   !   /   b   i   n   /   b   a   s   h  \n

Das ist richtig:

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

Verwenden Sie dos2unix(oder sed, tr, awk, perl, python...) Ihr Skript zu beheben , wenn dies das Problem ist.

Hier ist eine, mit der sowohl eine Stückliste als auch Tailing-CRs entfernt werden:

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


Beachten Sie, dass die Shell, mit der Sie das Skript ausführen, die angezeigten Fehlermeldungen geringfügig beeinflusst.

Hier sind drei Skripte, die nur ihren Namen ( echo $0) zeigen und die folgenden Shebang-Linien haben:

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

Wenn Sie sie unter bash ausführen, werden die folgenden Meldungen angezeigt:

$ ./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

Das Ausführen der falschen Skripte durch expliziten Aufruf des Interpreters ermöglicht die problemlose Ausführung des CRLF-Skripts:

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

Hier ist das Verhalten beobachtet unter ksh:

$ ./scriptWithCRLF
ksh: ./scriptWithCRLF: not found [No such file or directory]
$ ./scriptWithBom
./scriptWithBom[1]: #!/bin/bash: not found [No such file or directory]
./scriptWithBom

und unter dash:

$ ./scriptWithCRLF
dash: 2: ./scriptWithCRLF: not found
$ ./scriptWithBom
./scriptWithBom: 1: ./scriptWithBom: #!/bin/bash: not found
./scriptWithBom
jlliagre
quelle
2
Ein anderer Weg, um herauszufinden, ob dies das Problem ist, ist hexdump -C yourscript | head -n 1. Ich würde immer noch verwenden dos2unix yourscript, um es zu beheben.
Kevin M
Ja, das könnte sehr gut sein. Ich habe in Windows bearbeitet. Dinge für den Tipp.
Nicolas de Fontenay
1
Wenn es sich um ein CRLF-Problem handelt, wird keine #!/bin/bash no such file or directoryFehlermeldung angezeigt, da es keinen Grund gibt, etwas auszuführen oder zu öffnen #!/bin/bash. Es ist das, /bin/bash<CR>was ausgeführt werden würde.
Stéphane Chazelas
1
@StephaneChazelas Da dos2unix das Problem behoben hat, gibt es kaum Zweifel, dass es kein CRLF-Problem war. Die Fehlermeldung wurde wahrscheinlich nur ungenau transkribiert ..
jlliagre
6
dos2unixentfernt auch eine UTF-8-Stückliste. Eine UTF-8-Stückliste hätte die Fehlermeldung erklären können.
Stéphane Chazelas
17

Dies kann auch durch eine Stückliste in einem UTF-8-Skript verursacht werden. Wenn Sie das Skript in Windows erstellen, werden Sie manchmal am Anfang der Datei mit Junk-E-Mails konfrontiert.

teknopaul
quelle
Stückliste kann einfach mit awk entfernt werden, wie in stackoverflow.com/questions/1068650/…
pauxu
1
Beachten Sie, dass Visual Studio für Mac eine Stückliste einfügt.
Klarer
9

Tatsächlich ist das richtige Wort für das Bash-Skript das Folgende:

#!/usr/bin/env bash

Denn in freeBSD befindet sich bash in /usr/local/bin/bash

moebius_eye
quelle
13
"richtig" ist in solchen Fällen ein schwieriges Wort. Vielleicht wäre ein besserer Ausdruck "weniger fehleranfällig".
HalosGhost
1
Das ist auch schrecklich; Die Annahme, dass / usr existiert, ist eine schlechte IMO. Haiku zum Beispiel hat / usr nicht.
Jessicah
9

Sie können vi verwenden, um beide Probleme zu beheben, falls vorhanden:

vi <your_file>
:set ff=unix
:set nobomb
:wq
cwash
quelle
Die Antworten sollten so weit wie möglich in sich geschlossen sein. Die Frage erwähnt nicht zwei Probleme; Wenn Sie auf anderen Antworten aufbauen wollen, sollten Sie zumindest sagen, was sie sind. Besser noch, Sie sollten erklären, wie dies die Frage beantwortet.
G-Man,
Sehr schnelle Lösung, ohne weitere Windows-Tools herunterzuladen, danke!
Steampowered
1
@ G-Man Andere Antworten erwähnen dies bereits viel ausführlicher, als ich eingehen möchte. Keine Notwendigkeit zu wiederholen, aber wenn es nicht schmerzhaft offensichtlich ist, können Sie ein Windows-Zeilenende und ein verstecktes Windows-BOM-Zeichen haben. Ich denke, viele Leute, die Antworten scannen, schätzen die Kürze, anstatt in sich geschlossen zu sein, besonders wenn andere Antworten viel detaillierter sind.
Cwash
4

Wenn Sie nicht über dos2unix verfügen, können Sie dieses Problem auf diese Weise beheben.

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

Byte-Order Mark (BOM)

Dies kann durch eine Stückliste verursacht werden. Bei Wikipedia ist eine Stückliste eine

Die Byte Order Mark (BOM) ist ein Unicode-Zeichen, eine U + FEFF-Byte Order Mark (BOM), deren Darstellung als magische Zahl am Anfang eines Textstroms einem textverzehrenden Programm verschiedene Signale geben kann

Leider wird dem Linux-Kernel, der die She-Bang-Leitung verwaltet, nichts signalisiert. Sie können überprüfen Sie eine Stückliste haben durch Verwendung file,

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

Sie können die ersten Zeichen auch hexadezimal ausgeben und überprüfen, ob sie manuell mit einem der Stücklistenzeichen übereinstimmen

Sie können die Stücklistenzeichen entfernen, sobald Sie sie so kennen.

sed -i '1 s/^\xef\xbb\xbf//' *.txt
Fabien Haddadi
quelle
0

Ich hatte das Problem, indem ich versehentlich eine falsche ausführbare Bash-Datei zu dem PATHSkript hinzugefügt habe, und weil in meinem Skript der flexiblere #!/usr/bin/env bashShebang verwendet wurde (nimm die erste ausführbare Bash-Datei aus dem Pfad).

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

Ich habe GIT für Windows installiert, um cygwinmit Windows GIT-GUIs zusammenzuarbeiten (funktionierte nicht mit nativem Cygwin-Git ...). Ich habe das jetzt gelöst, indem ich zu #!/bin/bashsheband gewechselt und GIT für Windows von entfernt habe PATH.

jan
quelle
-3

Versuchen #!/bin/bash

Zweite Sache: find / -name bash
Dritte Sache:ls -al /bin/bash

Sebastian Szary
quelle
Oder einfach which bash. Wir wissen, dass es eins findet, weil es damit arbeitet bash script.sh.
Kevin
Wahr. Und wie bereits erwähnt, gibt es die viel portablere Methode / usr / bin / env, mit der ein Programm die Bash (oder einen anderen Interpreter) für Sie finden kann. Keine Notwendigkeit, einen Pah fest zu codieren.
Hennes