
Ich habe ein Shell-Skript, das nach einer Datei sucht /tmp/bbsnode1
und diese löscht, wenn die Existenz dieser Datei bestätigt wird. Ich möchte alle vorhandenen Dateien ( /tmp/bbsnode2
,, /tmp/bbsnode3
und ) löschen./tmp/bbsnode4
Löschen Sie sie aber nur, wenn alle vorhanden sind.
Folgendes habe ich bisher:
if [ -f /tmp/bbsnode1 ]
then
/usr/bin/rm /tmp/bbsnode1
fi
Antwort1
Ich würde eine Shell verwendenFunktionhierfür anstelle eines Skripts:
rm-all-or-none() {
for f; do
[ -f "$f" ] ||
{ printf '%s is not an existing file, no files removed\n' "$f" >&2
return 1;}
done
rm -fv -- "$@"
}
Dann würde ich es mit Klammererweiterung aufrufen, statt mit einem Glob. Globs werden nur in Dateien erweitert, dieexistieren, aber in diesem Fall möchten wir die Dateien angeben und sie nur entfernen, wennalledavon gibt es:
rm-all-or-none /tmp/bbsnode{1..4}
Längere gleichwertige Version:
rm-all-or-none() {
for f in "$@"; do
if [ -f "$f" ]; then
:
else
printf '%s is not an existing file, no files removed\n' "$f" >&2
return 1
fi
done
rm -fv -- "$@"
}
Siehe auch:
Antwort2
Sie können einen beliebigen Befehl verwenden, um ls
nach den Dateien zu suchen und sie in einer Zeile zu löschen
ls /tmp/bbsnode{1,2,3,4} &>/dev/null && rm /tmp/bbsnode{1,2,3,4}
Beachten Sie, dass es im Allgemeinen unsicher ist, solche Dinge in /tmp zu tun, da jeder andere Benutzer widersprüchliche Dateien mit denselben Namen erstellen könnte.
Eine kurze Erklärung:
Der Rückgabewert von ls
ist ungleich Null, wenn eine der Dateien nicht existiert. Das {1,2,3,4}
ist eine Klammererweiterung: es wird für jede Zahl zu einem String erweitert: /tmp/bbsnode{1,2,3,4}
ist also dasselbe wie /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
. Das &&
führt den nächsten Befehl nur aus, wenn der vorherige Befehl einen Rückgabewert von Null hatte, und rm
wird daher hier nur ausgeführt, wenn alle 4 Dateien existieren. Schließlich &> /dev/null
unterdrückt das die Ausgabe von ls
( &>
leitet sowohl stdout
als auch um stderr
, /dev/null
entfernt sie).
Unten eine weitere Lösung mit nur Shell-Builtins. Sie ähnelt der Antwort anderer, jedoch ohne zusätzliche Funktion oder Skript:
set -- /tmp/bbsnode{1,2,3,4}
(for f; do test -f "$f" || exit; done) && rm -- "$@"
Antwort3
In diesem speziellen Fall könnten Sie Folgendes tun:
set -- file[1-4]
[[ $# -eq 4 ]] && rm -f -- "$@"
Dies set
ist die Argumentliste für die Dateinamen, die mit einem der Werte file1
, file2
, file3
oder file4
1 übereinstimmen. Dann rm
werden diese Dateien nur dann ausgeführt, wenn die Anzahl der Argumente 4 ergibt, d. h. wenn alle Dateien vorhanden sind.
1: der Einfachheit halber verwende ich file
statt/tmp/bbsnode
Antwort4
Sie können dieses Skript mit dem Namen verwendenremoving_group
#!/usr/bin/bash
function check {
while (( "$#" )) ; do
if [ -f "$1" ] ; then
# echo "The file $1" ;
shift ;
else
# echo "The's no file $1";
return 1
fi
done
return 0
}
if check $@; then
while (( "$#" )) ; do
# echo "Remove $1" ;
rm "$1" ;
shift ;
done
fi
Die check
Funktion prüft, ob alle Argumente normale Dateien sind. Wenn die nächste Datei nicht existiert, kehrt die Funktion zurück 1
und es passiert nichts. Wenn alle Dateien existieren, 0
wird process zurückgegeben if check $@
, das die Dateien einzeln entfernt. Die zu prüfenden und zu entfernenden Dateien werden als Parameter in der Befehlszeile beschrieben, zum Beispiel
./removing_group /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
oder
./removing_group /tmp/bbsnode{1,2,3,4}