' ist ein Verzeichnisfehler ', wenn versucht wird, den Verzeichnisnamen an die Funktion

In meinem Bash-Skript verwende ich find, um die Ordnernamen per Platzhalter abzurufen:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff ${i} done doStuff() { echo ${1} return ${1}"/hello"; } 

Das Problem ist, dass ich dies bekomme, wenn ich dies tue Der folgende Fehler (sagen wir, dass $ {i} „home / me / my_directory“ entspricht):

line 111: "/home/me/my_directory": is a directory. 

(Zeile 111 ist die Zeile mit „doStuff“ „)

Ich habe dies erfolglos versucht:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff "${i}" done 

Anscheinend liegt es daran, dass das Programm versucht, das auszuführen Verzeichnis, aber ich möchte es nur als Zeichenfolge, die ich bearbeiten kann.

Kommentare

  • Hmmm …. Laut der Bash-Manpage. … Der Befehl return builtin in bash wird verwendet, um einen EXIT-Code (Ganzzahl) zurückzugeben, der kein String-Parameter ist.
  • Sie können auch find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
  • Googler : Eine weitere großartige Quelle, um diese Fehlermeldung zu erhalten ge ist //a wrong bash line comment anstelle von #a correct bash line comment

Antwort

Anführungszeichen und Befehlsersetzung sind hier Ihre Probleme.

Das spezifische Problem, auf das Sie stoßen, besteht darin, dass die Shell versucht, einen Befehl mit dem Namen mit der Umgebungsvariablen stuff=doStuff.
Was Sie wirklich wollen (wenn ich richtig interpretiere), ist doStuff mit dem Wert $i als Argument, wobei die Ausgabe der Variablen stuff zugewiesen wird. Die Möglichkeit dazu besteht darin, Ihren Befehl in $() zu verpacken. Zum Beispiel:

stuff="$(doStuff "$i")" 

Beachten Sie, wie ich auch alles in Anführungszeichen setze. Dies soll verhindern, dass die Shell Wörter aufteilt, von denen Sie nicht möchten, dass sie Wörter aufteilen (es wird ein einzelnes Argument von /foo/bar baz in /foo/bar und baz).

Auch die Ausgabe Ihrer Funktion wird als Rückgabewert verwendet, nicht return.

Da Sie mehr Anführungszeichen verwenden sollten, sollten Sie diese auch zu allem anderen hinzufügen. Hier ist eine vollständige Version Ihres Skripts:

doStuff() { echo "${1}" >&2 printf "%s/hello" "$1"; } IFS=$"\n" for i in $(find "${directory}" -mindepth 1 -type d -name "${wildcard}"); do stuff="$(doStuff "${i}")" done 

Sie müssen die Funktionsdefinition eingeben, bevor Sie versuchen, sie zu verwenden. Shell wird nicht wie kompilierte Programme analysiert, bei denen die Datei mehrmals durchlaufen wird. Sie ist von oben nach unten.
Ich habe auch doStuff geändert, um das echo an STDERR, wo es auf dem Terminal angezeigt wird, und dann sendet die printf an STDOUT, wo es in der Variablen stuff.

Beachten Sie, dass dies immer noch ein Problem darstellt, wenn eines Ihrer Verzeichnisse eine neue Zeile enthält. Dies ist jedoch eine Einschränkung der Shell. Das einzige Zeichen, das ein Dateipfad nicht kann enthalten ist ein NULL-Zeichen (\0). Bash und andere Shells können jedoch kein NULL-Zeichen in einer Zeichenfolge speichern (nicht alle, aber viele. Ich weiß, dass zsh kann), also können Sie “ Verwenden Sie es nicht als Trennzeichen.

Kommentare

  • Ich wollte das nur hinzufügen, wenn Sie vor / nach =, es bringt es durcheinander. z.B. MY_VAR = ' / some / path ' ist gültig, aber MY_VAR = ' / some / Pfad ' oder MY_VAR = ' / some / Pfad ' ist nicht

Antwort

Das ist eine gute Anstrengung, aber es zeigt, dass Sie versuchen, bash als wäre es eine Programmiersprache, wenn es sich tatsächlich um eine einfache Skriptsprache handelt. Das Problem mit Ihrer stuff=doStuff arg -Konstruktion besteht darin, dass bash nicht bedeutet, was Sie denken, dass es bedeutet. Für bash ist stuff=doStuff eine Variablenzuweisung und arg ein Befehl. Ich schlage vor, Sie lesen die folgenden zwei Links:

Eine funktionierende Version von etwas ähnlichem wie dem, was Sie haben, wäre

doStuff () { echo "$1/hello" } stuff=$(doStuff "$i") 

Antwort

Die Zeile mit dem Fehler macht nicht das, was Sie denken:

Es setzt zuerst die Umgebungsvariablen auf die Zeichenfolge „doStuff“ und versucht dann, $ {i} als Befehl auszuführen. Und da $ {i} ein Verzeichnis ist, schlägt dies mit der angegebenen Fehlermeldung fehl.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.