Die Ausgabe von ls zu verwenden, um Dateinamen zu erhalten, ist eine schlechte Idee . Es kann zu Fehlfunktionen und sogar zu gefährlichen Skripten führen. Das liegt daran, dass ein Dateiname jedes beliebige Zeichen außer / und dem Zeichen null enthalten kann, und ls verwendet keines dieser Zeichen als Trennzeichen. Wenn ein Dateiname also ein Leerzeichen oder einen Zeilenumbruch enthält, werden Sie unerwartete Ergebnisse erhalten.
Es gibt zwei sehr gute Möglichkeiten, über Dateien zu iterieren. Hier habe ich einfach echo verwendet, um zu demonstrieren, wie man etwas mit dem Dateinamen macht; man kann aber alles verwenden.
Die erste ist, die nativen Globbing-Funktionen der Shell zu verwenden.
for dir in */; do
echo "$dir"
done
Die Shell erweitert */ in separate Argumente, die die for-Schleife liest; selbst wenn der Dateiname ein Leerzeichen, einen Zeilenumbruch oder ein anderes seltsames Zeichen enthält, sieht for jeden vollständigen Namen als atomare Einheit; die Liste wird in keiner Weise geparst.
Wenn Sie rekursiv in Unterverzeichnisse gehen wollen, dann geht das nicht, es sei denn, Ihre Shell hat einige erweiterte Globbing-Funktionen (wie bash‘s globstar. Wenn Ihre Shell nicht über diese Funktionen verfügt oder wenn Sie sicherstellen wollen, dass Ihr Skript auf einer Vielzahl von Systemen funktioniert, dann ist die nächste Option die Verwendung von find.
find . -type d -exec echo '{}' \;
Hier wird der Befehl find echo aufrufen und ihm ein Argument des Dateinamens übergeben. Er tut dies einmal für jede Datei, die er findet. Wie im vorigen Beispiel gibt es kein Parsen einer Liste von Dateinamen; stattdessen wird ein Dateiname vollständig als Argument gesendet.
Die Syntax des Arguments -exec sieht ein wenig komisch aus. find nimmt das erste Argument nach -exec und behandelt es als das auszuführende Programm, und jedes weitere Argument wird als Argument an dieses Programm übergeben. Es gibt zwei spezielle Argumente, die -exec sehen muss. Das erste ist {}; dieses Argument wird durch einen Dateinamen ersetzt, den die vorherigen Teile von find erzeugen. Das zweite ist ;, das find wissen lässt, dass dies das Ende der Liste der an das Programm zu übergebenden Argumente ist; find braucht dies, weil Sie mit weiteren Argumenten fortfahren können, die für find und nicht für das ausgeführte Programm bestimmt sind. Der Grund für [ Die Ausgabe vonlszu verwenden, um Dateinamen zu erhalten, ist eine schlechte Idee ]&003. Es kann zu Fehlfunktionen und sogar zu gefährlichen Skripten führen. Das liegt daran, dass ein Dateiname jedes beliebige Zeichen außer/und dem Zeichennullenthalten kann, undls` verwendet keines dieser Zeichen als Trennzeichen. Wenn ein Dateiname also ein Leerzeichen oder einen Zeilenumbruch enthält, werden Sie unerwartete Ergebnisse erhalten.
Es gibt zwei sehr gute Möglichkeiten, über Dateien zu iterieren. Hier habe ich einfach echo verwendet, um zu demonstrieren, wie man etwas mit dem Dateinamen macht; man kann aber alles verwenden.
Die erste ist, die nativen Globbing-Funktionen der Shell zu verwenden.
for dir in */; do
echo "$dir"
done
Die Shell erweitert */ in separate Argumente, die die for-Schleife liest; selbst wenn der Dateiname ein Leerzeichen, einen Zeilenumbruch oder ein anderes seltsames Zeichen enthält, sieht for jeden vollständigen Namen als atomare Einheit; die Liste wird in keiner Weise geparst.
Wenn Sie rekursiv in Unterverzeichnisse gehen wollen, dann geht das nicht, es sei denn, Ihre Shell hat einige erweiterte Globbing-Funktionen (wie bash’s globstar. Wenn Ihre Shell nicht über diese Funktionen verfügt oder wenn Sie sicherstellen wollen, dass Ihr Skript auf einer Vielzahl von Systemen funktioniert, dann ist die nächste Option die Verwendung von find.
find . -type d -exec echo '{}' \;
Hier wird der Befehl find echo aufrufen und ihm ein Argument des Dateinamens übergeben. Er tut dies einmal für jede Datei, die er findet. Wie im vorigen Beispiel gibt es kein Parsen einer Liste von Dateinamen; stattdessen wird ein Dateiname vollständig als Argument gesendet.
Die Syntax des Arguments -exec sieht ein wenig komisch aus. find nimmt das erste Argument nach -exec und behandelt es als das auszuführende Programm, und jedes weitere Argument wird als Argument an dieses Programm übergeben. Es gibt zwei spezielle Argumente, die -exec sehen muss. Das erste ist {}; dieses Argument wird durch einen Dateinamen ersetzt, den die vorherigen Teile von find erzeugen. Das zweite ist ;, das find wissen lässt, dass dies das Ende der Liste der an das Programm zu übergebenden Argumente ist; find braucht dies, weil Sie mit weiteren Argumenten fortfahren können, die für find und nicht für das ausgeführte Programm bestimmt sind. Der Grund für ist, dass die Shell auch ; speziell behandelt - es stellt das Ende eines Befehls dar, also müssen wir ihm entkommen, damit die Shell es als Argument an find übergibt, anstatt es für sich selbst zu verbrauchen; eine andere Möglichkeit, die Shell dazu zu bringen, es nicht speziell zu behandeln, besteht darin, es in Anführungszeichen zu setzen: ';' funktioniert für diesen Zweck genauso gut wie \;.