Nehmen wir an, ich habe ein einfaches dummes Skript, das Dateien entfernt, indem es endet und so aussieht:
rm *.uvw *.xyz
Das Skript oder rm
, um genau zu sein, schreibt Nachrichten auf stderr, wenn es nicht mindestens eine Datei mit der angegebenen Endung finden kann.
Nehmen wir nun an, das Skript ist etwas größer und macht etwas mehr mit etwas mehr Dateitypen und es interessiert mich nicht, welche Dateitypen existieren und welche nicht, aber die Beschwerden über nicht vorhandene Dateitypen behindern den Rest Die Ausgabe und die Fehlermeldungen interessieren mich mehr, daher möchte ich die Ausgabe filtern:
rm *.uvw *.xyz 2>&1 | grep -v "No such file or directory"
Das funktioniert größtenteils gut, entfernt aber den Meldungsteil von interaktiven Dialogen, die zum Beispiel fragen, ob eine schreibgeschützte Datei gelöscht werden soll, sodass ich ohne entsprechende Meldung gefragt werde.
Ich verstehe dieses Verhalten nicht und konnte keine zugehörigen Informationen finden. Kann das jemand erklären?
Akzeptierte Antwort:
Das Problem
Wenn rm zur Eingabe auffordert, fügt es am Ende der Eingabeaufforderung keinen Zeilenumbruch ein:
$ rm *.uvw *.xyz
rm: remove write-protected regular empty file 'a.xyz'?
grep
ist zeilenbasiert. Es können nur ganze Zeilen verarbeitet werden. Es kann nicht sagen, ob die Zeile gedruckt werden soll, bis die Zeile vollständig ist. Daher Standardhilfsprogramme für den Umgang mit Pufferung, wie stdbuf
, kann nicht helfen.
Die Lösung
Verwenden Sie nullglob und entfernen Sie die Meldungen zu fehlenden Dateien.
Ohne nullglob erscheinen die unerwünschten Nachrichten:
$ rm *.uvw *.xyz
rm: cannot remove '*.uvw': No such file or directory
rm: remove write-protected regular empty file 'a.xyz'? n
Damit wird die „No such file or directory“-Meldung unterdrückt:
$ shopt -s nullglob
$ rm *.uvw *.xyz
rm: remove write-protected regular empty file 'a.xyz'? n
Verfeinerung
Wenn es überhaupt keine Datei gibt, die zu einem der beiden Globs passt, erscheint eine andere Fehlermeldung:
$ shopt -s nullglob
$ rm *.uvw *.xyz
rm: missing operand
Try 'rm --help' for more information.
Eine einfache Möglichkeit, dies zu vermeiden, besteht darin, sicherzustellen, dass mindestens eine solche Datei vorhanden ist:
shopt -s nullglob
[ -e "deleteme.xyz" ] ||touch deleteme.xyz
rm *.uvw *.xyz
Seit deleteme.xyz
sowieso gelöscht wird, kann es nicht schaden, es anzufassen, bevor wir rm
ausführen .