我经常调用以下脚本
清理.sh
#!/bin/bash
DEFAULT_LIMIT=10
INPUT=$1
PATTERN=$2
LIMIT=$3
if [ "$INPUT" == "" ] || [ "$PATTERN" == "" ]
then
echo "usage: $0 INPUT PATTERN [LIMIT]"
exit 1;
fi
if [ "$LIMIT" == "" ]
then
LIMIT=$DEFAULT_LIMIT
fi
find /var/project/project1 -maxdepth 1 -type d -name "${INPUT}-${PATTERN}*" -printf '%T@ %p\n'|sort -nr|tail -n+$LIMIT|cut -f 2- -d " "|xargs -i rm -rf {}
所以这个应该从 /var/project/project1
很少出乎意料地(尽管非常重要)它会从 /var/project/project1
中删除预期目录以外的目录。知道为什么吗? cut 的行为是否为 2- 明确定义? f 和 field# 之间可以有空格吗?这不是故意写的,而是一个错误,但不太确定这段代码是否是导致意外删除的原因。
这很少可重现,因此不确定修复此问题 (cut -f2 -d ""
) 是否会解决我的问题
最佳答案
您当前的实现将在任何有空格的文件上中断。这就是 xargs
的本质,以及为什么它被认为是危险的,除非使用 -0(这在您当前的布局中是不可能的)。
例如,假设一个名为“foo bar”的文件进入xargs
。 xargs
将像这样调用 rm:
rm -rf foo bar
它没有删除“foo bar”,而是删除了一个名为 foo
的文件和一个名为 bar
的文件。如果将剪切命令更改为 -f2
而不是 -f2-
,它仍会在包含空格的文件上中断,但只会删除 foo
.
这是一个处理所有可能文件名的例子:
#!/bin/bash
input=$1
pattern=$2
limit=${3:-10} # use 10 if $3 is not set
if [[ -z $input || -z $pattern ]]
then
echo "usage: $0 INPUT PATTERN [LIMIT]"
exit 1;
fi
dirs=()
while IFS= read -r -d '' latest # \0 is used as a delimiter, since it is not valid in a filename
do
dirs+=("$latest") # append files to the array in mtime sorted order, oldest first
done < <(find /var/project/project1 -maxdepth 1 -type d -name "${input}-${pattern}*" -printf '%T@ %p\0' | sort -zn)
dirs=("${dirs[@]#* }") # remove mtime from the elements
rm -rf "${dirs[@]:0:$limit}"
关于linux - 剪切-f 2- -d "",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12188970/