我有以下经常调用的脚本
#!/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 {}
所以这个应该从$LIMIT
删除前缀为$INPUT-$PATTERN
的{{1}}目录,并且很少出乎意料地(尽管非常关键)删除目标以外的目录。 /var/project/project1
。知道为什么吗?切割的行为是否定义为2-?我们可以在f和场之间有空格#?这不是故意写的,而是一个错误,但不太确定这段代码是否是造成这种意外删除的代码。
这很难重现,因此不确定修复此问题(/var/project/project1
)是否能解决我的问题
答案 0 :(得分:3)
您当前的实现将在具有空格的任何文件上中断。这是xargs
的性质,以及除非使用-0(在当前布局中无法实现),否则它被认为是危险的。
作为一个例子,假设一个文件使其成为xargs
,称为“foo bar”。 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}"
答案 1 :(得分:0)
请注意,即使我们要求第二个字段,echo "one" | cut -f 2 -d " "
也会显示“一个”。
那么当你打电话给cut -f 2- -d " "
并且只有一个领域时,你会怎么想?如果没有,则添加-s
选项。
换句话说改变
cut -f 2- -d " "
到
cut -s -f 2- -d " "
希望它有所帮助。