Das Bash-Skript druckt "Befehl nicht gefunden" in leere Zeilen


110

Jedes Mal, wenn ich ein Skript über bash scriptname.shdie Befehlszeile in Debian ausführe , erhalte ich Command Not founddas Ergebnis des Skripts.

Das Skript funktioniert, aber Command Not Foundfür jede leere Zeile wird immer eine Anweisung auf dem Bildschirm gedruckt. Jede leere Zeile führt dazu, dass ein Befehl nicht gefunden wird.

Ich führe das Skript aus dem /varOrdner aus.

Hier ist das Skript:

#!/bin/bash

echo Hello World

Ich führe es aus, indem ich Folgendes eingebe:

bash testscript.sh

Warum sollte das passieren?


Im Ernst, net ist voll von solchen Beschwerden. Shell ist ein sehr schwacher und lahmer Dolmetscher. Wenig hier und da und es scheitert. Sie müssen sogar alle Leerzeichen im Skript beobachten. Mein Skript schlug aufgrund eines unsichtbaren Zeilenvorschubzeichens fehl. Wahrscheinlich ist dies nur eine Skriptsprache, in der Leerzeichen wichtig sind!
Atul

1
Verwenden Sie bash -x scriptname.shdiese Option , um den Fehler zu verfolgen. - In meinem Fall war es eine unter Windows gespeicherte sh-Datei mit VSCode und Zeilenenden als "CRLF". In VSCode in der unteren rechten Ecke können Sie den Zeilenabschluss von "CRLF" in "LF" ändern. Diese Datei wurde hochgeladen und konnte schließlich mit ausgeführt werden bash scriptname.sh.
Kai Noack

Dies ist definitiv ein Duplikat von stackoverflow.com/questions/39527571/…, aber viele Antworten hier erklären eine Reihe anderer Situationen, in denen Sie aus anderen Gründen den Befehl "Befehl nicht gefunden" erhalten. Besuchern wird empfohlen, alle Antworten zu lesen, wenn es bei Ihrem Problem nicht speziell um Leerzeilen geht.
Tripleee

Antworten:


160

Stellen Sie sicher, dass Ihre erste Zeile lautet:

#!/bin/bash

Geben Sie Ihren Pfad zum Bash ein, wenn dies nicht der Fall ist /bin/bash


Versuchen Sie zu laufen:

dos2unix script.sh

Dadurch werden Zeilenenden usw. von Windows in das Unix-Format konvertiert. dh es entfernt \ r (CR) von den Zeilenenden, um sie von \r\n (CR+LF)zu zu ändern \n (LF).

Weitere Details zum dos2unixBefehl (Manpage)


Eine andere Möglichkeit, um festzustellen, ob Ihre Datei im Dos / Win-Format vorliegt:

cat scriptname.sh | sed 's/\r/<CR>/'

Die Ausgabe sieht ungefähr so ​​aus:

#!/bin/sh<CR>
<CR>
echo Hello World<CR>
<CR>

Dadurch wird der gesamte Dateitext ausgegeben, der <CR>für jedes \rZeichen in der Datei angezeigt wird .


Das ist wahrscheinlich nicht notwendig, da er es direkt mit betreibt bash scriptname.sh(aber es ist natürlich immer noch eine gute Übung).
Paxdiablo

1
Hi #! / Bin / bash ist die erste Zeile meines Skripts
David

1
@chown - Ich hatte das gleiche Problem auf dem Mac. Ich bin über diesen Beitrag gestolpert. Ich bin mir nicht sicher, ob es dem OP geholfen hat oder nicht. Aber Ihre Lösung hat mir geholfen.
Prashant

1
Vielen Dank. Dies war genau das Problem, mit dem ich konfrontiert war. Diese Antworten haben es geschafft.
Slayedbylucifer

5
Wie können Sie während der Fahrt eine Antwort auf eine Programmierfrage schreiben?
Omar Tariq

61

Sie können es verwenden bash -x scriptname.sh, um es zu verfolgen.


47

Ich bin auch auf ein ähnliches Problem gestoßen. Das Problem scheinen Berechtigungen zu sein. Wenn du eine machstls -l , können Sie möglicherweise feststellen, dass in Ihrer Datei das Ausführungsbit möglicherweise NICHT aktiviert ist. Dadurch kann das Skript NICHT ausgeführt werden. :) :)

Als @artooro im Kommentar hinzugefügt:

Um dieses Problem zu beheben, führen Sie es aus chmod +x testscript.sh


4
Um dieses Problem zu beheben, führen Siechmod +x testscript.sh
artooro

Dies war die Antwort, die für mich funktionierte. Mir wurde immer gesagt, dass ich keine Erlaubnis habe, also habe ich sie sudo'ed und mir wurde gesagt, dass der Befehl nicht gefunden wurde. Ich habe nicht daran gedacht, die Berechtigungen zu überprüfen.
DiamondDrake

1
Dank Lypso345 löste dies das Problem, das ich hatte.
Ammills01

chmod 777 testscript.sh FTW
GeneCode

16

Dies mag trivial sein und hat nichts mit der Frage des OP zu tun, aber ich habe dies zu Beginn des Lernens von Skripten oft falsch gemacht

VAR_NAME = $(hostname)
echo "the hostname is ${VAR_NAME}"  

Dies führt zu einer Antwort "Befehl nicht gefunden". Der richtige Weg ist, die Leerzeichen zu entfernen

VAR_NAME=$(hostname)

11

Wenn das Skript seine Arbeit (relativ) gut macht, läuft es in Ordnung. Ihr Problem ist wahrscheinlich eine einzelne Zeile in der Datei, die auf ein Programm verweist, das sich entweder nicht im Pfad befindet, nicht installiert, falsch geschrieben oder ähnlich ist.

Eine Möglichkeit besteht darin, ein set -xoben in Ihrem Skript zu platzieren oder es mit bash -xstatt nur auszuführenbash auszuführen. werden die Zeilen vor der Ausführung ausgegeben, und Sie müssen normalerweise nur die Befehlsausgabe unmittelbar vor dem Fehler überprüfen, um festzustellen, was das Problem verursacht

Wenn es, wie Sie sagen, die leeren Zeilen sind, die die Probleme verursachen, möchten Sie möglicherweise überprüfen, was tatsächlich in ihnen enthalten ist. Lauf:

od -xcb testscript.sh

und stellen Sie sicher, dass es keine "unsichtbaren" lustigen Zeichen wie den CTRL-M(Wagenrücklauf) gibt, die Sie möglicherweise mit einem Windows-Editor erhalten.


+1 für den Befehl 'od'! Das ist cool, das wusste ich nicht! Vielen Dank!
Chown

11

Unter Bash für Windows habe ich falsch versucht, es auszuführen

run_me.sh 

ohne ./ am anfang und habe den gleichen fehler bekommen.

Für Personen mit Windows-Hintergrund sieht das richtige Formular überflüssig aus:

./run_me.sh



6

Um dies auszuführen, müssen Sie beispielsweise den vollständigen Pfad dafür angeben

/home/Manuel/mywrittenscript

In der Tat kümmert sich die Shell überhaupt nicht um Dateierweiterungen. Ich bin mir nicht sicher, ob dies als separate Antwort veröffentlicht werden sollte.
Tripleee

Natürlich werden .in Linux-Dateisystemen im Gegensatz zu Windows-Erweiterungen nur als Teil des Namens verwendet und sagen nichts über den Inhalt der Datei aus. Ich darf in meinem Fall keine Einschränkung sagen .
Masood Moghini

6

Wenn Sie Notepad ++ haben und diese .sh-Fehlermeldung erhalten: "Befehl nicht gefunden" oder diese Autoconf-Fehlermeldung "Zeile 615: ../../autoconf/bin/autom4te: Keine solche Datei oder kein solches Verzeichnis" .

Gehen Sie auf Ihrem Notepad ++ zu Bearbeiten -> EOL-Konvertierung und überprüfen Sie Macinthos (CR) . Dadurch werden Ihre Dateien bearbeitet. Ich empfehle auch, alle Dateien mit diesem Befehl zu überprüfen, da bald ein solcher Fehler auftreten wird.


Danke dafür. Für meinen Fall habe ich ein Skript in der Busybox Linux Distribution ausgeführt. Hatte den gleichen Fehler "nicht gefunden" in allen leeren Zeilen in meinen Skripten. Es gab auch Probleme mit der if / else-Anweisung. Das Ändern von EOL in Notepad ++ in Unix hat das Problem behoben.
GeneCode

4

Hatte das gleiche Problem. Unglücklicherweise

dos2unix winfile.sh
bash: dos2unix: command not found

Also habe ich das getan, um zu konvertieren.

 awk '{ sub("\r$", ""); print }' winfile.sh > unixfile.sh

und dann

bash unixfile.sh

2

Probleme beim Ausführen von Skripten können auch mit einer fehlerhaften Formatierung mehrzeiliger Befehle zusammenhängen, z. B. wenn Sie nach dem Zeilenumbruch "\" ein Leerzeichen haben. ZB das:

./run_me.sh \ 
--with-some parameter

(Bitte beachten Sie den zusätzlichen Speicherplatz nach "\") verursacht Probleme, aber wenn Sie diesen Speicherplatz entfernen, läuft er einwandfrei.


0

Ich hatte auch einige von Cannot execute command. Alles sah korrekt aus, aber tatsächlich hatte ich &nbsp;direkt vor meinem Befehl einen nicht zerbrechlichen Raum, der natürlich mit bloßem Auge nicht zu erkennen war:

if [[ "true" ]]; then
  &nbsp;highlight --syntax js "var i = 0;"
fi

Was in Vim so aussah:

if [[ "true" ]]; then
  highlight --syntax js "var i = 0;"
fi

Erst nachdem shellcheckich die Bash-Skriptprüfung ausgeführt hatte, fand ich das Problem.


shellcheckist online verfügbar, obwohl Sie Ihr Skript natürlich genau kopieren und einfügen müssen, damit dies hilft. shellcheck.net
Tripleee

0

Ich bin heute darauf gestoßen und habe geistesabwesend die Dollar-Eingabeaufforderung $(vor einer Befehlszeichenfolge) in das Skript kopiert .


-1

Fügen Sie das aktuelle Verzeichnis (.) Zu PATH hinzu, um ein Skript ausführen zu können, indem Sie einfach seinen Namen eingeben, der sich im aktuellen Verzeichnis befindet:

PATH=.:$PATH

1
Dies wird als Sicherheitslücke angesehen. NICHT .ZU IHREM WEG HINZUFÜGEN.
gniourf_gniourf

Erklärung, warum diese „Antwort“ ist eine schlechte Idee: superuser.com/questions/156582/...
jmng

-1

Möglicherweise möchten Sie Ihre .bashrc- und .bash_profile-Dateien mit Aliasnamen aktualisieren, um den von Ihnen eingegebenen Befehl zu erkennen.

.bashrc- und .bash_profile-Dateien sind versteckte Dateien, die sich wahrscheinlich auf Ihrem Laufwerk C: befinden, auf dem Sie Ihre Programmdateien speichern.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.