
我有一個 shell 腳本,用於查找文件/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 -- "$@"
}
然後我會使用大括號擴充來呼叫它,而不是 glob。 Glob 只擴展到以下文件存在,但在這種情況下,我們想要指定文件並且僅在以下情況下刪除它們:全部其中存在:
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
非零。 is{1,2,3,4}
大括號擴展:它擴展為每個數字的字串:所以/tmp/bbsnode{1,2,3,4}
與 相同/tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
。&&
僅當當前一個命令的回傳值為零時,才會執行下一個命令,因此這裡僅rm
當所有 4 個檔案都存在時才執行。最後,&> /dev/null
抑制輸出ls
(&>
重定向stdout
和stderr
,/dev/null
擺脫它)。
下面是另一個僅包含 shell 內建函數的解決方案。它與其他人的回答類似,但沒有額外的函數或腳本:
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 -- "$@"
這是與、或1set
中任何一個匹配的文件名的參數列表,然後僅當參數數量等於 4(即所有文件都存在)時才顯示這些文件。 file1
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
將是 process if check $@
,這將一一刪除檔案。用於檢查和刪除的檔案在命令列中描述為參數,例如
./removing_group /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4
或者
./removing_group /tmp/bbsnode{1,2,3,4}