
У меня есть скрипт оболочки, который ищет файл, /tmp/bbsnode1
и если существование этого файла верно, он удаляет его. Что я хотел бы сделать, так это если существует несколько файлов ( /tmp/bbsnode2
, /tmp/bbsnode3
, и /tmp/bbsnode4
), удалить их все.Но удаляйте их только в том случае, если они все существуют.
Вот что у меня есть на данный момент:
if [ -f /tmp/bbsnode1 ]
then
/usr/bin/rm /tmp/bbsnode1
fi
решение1
Я бы использовал ракушкуфункциядля этого, а не скрипта:
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 -- "$@"
}
Тогда я бы назвал это, используя расширение скобок, а не глобус. Глобусы расширяются только до файлов, которыесуществовать, но в этом случае мы хотим указать файлы и удалить их только есливсеиз них существуют:
rm-all-or-none /tmp/bbsnode{1..4}
Более длинная эквивалентная версия:
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 -- "$@"
}
Также см:
решение2
Вы можете использовать произвольную команду, например, ls
для проверки файлов и их удаления в одной строке.
ls /tmp/bbsnode{1,2,3,4} &>/dev/null && rm /tmp/bbsnode{1,2,3,4}
Обратите внимание, что в целом делать такие вещи в /tmp небезопасно, поскольку любой другой пользователь может создать конфликтующие файлы с такими же именами.
Краткое пояснение:
Возвращаемое значение ls
не равно нулю, если один из файлов не существует. {1,2,3,4}
Расширение скобок is: оно расширяется до строки для каждого числа: so /tmp/bbsnode{1,2,3,4}
то же самое, что и /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
. &&
Выполняет следующую команду только в том случае, если предыдущая команда имеет нулевое возвращаемое значение, и поэтому здесь rm
выполняется только в том случае, если существуют все 4 файла. Наконец, &> /dev/null
подавляет вывод ls
( &>
перенаправляет stdout
и stderr
, /dev/null
избавляется от него).
Ниже еще одно решение только с shell builtins. Это похоже на то, что ответили другие, но без дополнительной функции или скрипта:
set -- /tmp/bbsnode{1,2,3,4}
(for f; do test -f "$f" || exit; done) && rm -- "$@"
решение3
В этом конкретном случае вы могли бы сделать:
set -- file[1-4]
[[ $# -eq 4 ]] && rm -f -- "$@"
Это set
список аргументов для имен файлов, которые соответствуют любому из , file1
или 1 , а затем эти файлы загружаются только в том случае, если количество аргументов равно 4, то есть если все файлы существуют. file2
file3
file4
rm
1: для простоты я использую file
вместо/tmp/bbsnode
решение4
Вы можете использовать этот скрипт под названиемremoving_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
Функция check
проверяет все свои аргументы на то, что они являются обычными файлами. Если следующий файл не существует, функция возвращается 1
и ничего не происходит. Если все файлы существуют, то возвращается 0
процесс if check $@
, который удалит файлы один за другим. Файлы для проверки и удаления описаны как параметры в командной строке, например
./removing_group /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
или
./removing_group /tmp/bbsnode{1,2,3,4}