
Tengo un script de shell que busca un archivo y /tmp/bbsnode1
, si la existencia de ese archivo es cierta, lo elimina. Lo que me gustaría hacer es si existen varios archivos ( /tmp/bbsnode2
, /tmp/bbsnode3
y /tmp/bbsnode4
), eliminarlos todos.Pero sólo elimínelos si todos existen.
Esto es lo que tengo hasta ahora:
if [ -f /tmp/bbsnode1 ]
then
/usr/bin/rm /tmp/bbsnode1
fi
Respuesta1
yo usaría un caparazónfunciónpara esto, en lugar de un guión:
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 -- "$@"
}
Entonces lo llamaría usando expansión de llaves, en lugar de globo. Los globos sólo se expanden a archivos queexistir, pero en este caso queremos especificar los archivos y solo eliminarlos sitodode ellos existen:
rm-all-or-none /tmp/bbsnode{1..4}
Versión equivalente más larga:
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 -- "$@"
}
Ver también:
Respuesta2
Podrías usar un comando arbitrario como ls
verificar los archivos y eliminarlos en una línea.
ls /tmp/bbsnode{1,2,3,4} &>/dev/null && rm /tmp/bbsnode{1,2,3,4}
Tenga en cuenta que, en general, no es seguro hacer este tipo de cosas en /tmp porque cualquier otro usuario podría crear archivos conflictivos con los mismos nombres.
Una breve explicación:
El valor de retorno de ls
no es cero si uno de los archivos no existe. La {1,2,3,4}
expansión de llaves es: se expande a una cadena para cada número: por lo tanto, /tmp/bbsnode{1,2,3,4}
es lo mismo que /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
. Ejecuta &&
el siguiente comando solo si el comando anterior tiene un valor de retorno cero, por lo que aquí rm
solo se ejecuta si existen los 4 archivos. Finalmente, &> /dev/null
suprime la salida de ls
( &>
redirecciona ambos stdout
y stderr
, /dev/null
se deshace de ella).
A continuación, otra solución con funciones integradas de shell únicamente. Es similar a lo que otros han respondido pero sin una función o script adicional:
set -- /tmp/bbsnode{1,2,3,4}
(for f; do test -f "$f" || exit; done) && rm -- "$@"
Respuesta3
En este caso particular podrías hacer:
set -- file[1-4]
[[ $# -eq 4 ]] && rm -f -- "$@"
Esta set
es la lista de argumentos para los nombres de archivos que coinciden con cualquiera de , file1
o 1 y luego son esos archivos solo si el número de argumentos es igual a 4, es decir, si todos los archivos existen. file2
file3
file4
rm
1: por simplicidad, uso file
en lugar de/tmp/bbsnode
Respuesta4
Podrías usar este script, llamadoremoving_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
La check
función verifica que todos sus argumentos sean archivos normales. Si el siguiente archivo no existe, la función regresa 1
y no sucede nada. Si todos los archivos existen, 0
se procesará la devolución if check $@
, lo que eliminará los archivos uno por uno. Los archivos para verificar y eliminar se describen como parámetros en la línea de comando, por ejemplo
./removing_group /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
o
./removing_group /tmp/bbsnode{1,2,3,4}