我相当原始的 shell 脚本有两个参数:第一个是位置,第二个是需要删除的文件数量。由于某种原因,即使我给出了示例 3 的参数,它也只删除了一个文件。代码:
#!/bin/bash
for i in {0..$2}
do
find $1 -type f | head -1 | xargs rm
done
更新 此代码似乎由于某种原因删除了两个文件:
#!/bin/bash
for i in eval {0..$2}
do
find "$1" -type f | head -1 | xargs rm
done
答案1
这是一个优先级问题。括号扩展内的变量不会被解释,因为括号被求值前变量被扩展。为了说明这一点,请运行以下命令:
$ var=3
$ set -x
$ echo {0..$var}
+ echo '{0..3}'
{0..3}
正如您所看到的,echo {0..$var}
被扩展为echo '{0..3}'
,因此文字字符串{0..3}
并不0 1 2 3
像您所期望的那样。
解决这个问题的一种方法是使用eval
:
$ eval echo {0..$var}
+ eval echo '{0..3}'
++ echo 0 1 2 3
0 1 2 3
所以你可以将脚本更改为:
#!/bin/bash
for i in $(eval echo {0..$2})
do
find "$1" -type f | head -1 | xargs rm
done
但这既危险又丑陋。这样会更好:
#!/bin/bash
for((i=0;i<=$2;i++))
do
find "$1" -type f | head -1 | xargs rm --
done
带有一些基本安全测试并且可以处理任意文件名(包括名称中带有换行符的文件)的更好版本(如果您使用的是 GNU 工具)是:
#!/bin/bash
if [[ $# -ne 2 ]]; then
echo "We need 2 arguments!"
exit
fi
if [[ ! $2 =~ ^[0-9]+$ ]]; then
echo "The second argument ('$2') must be a number!"
exit;
fi
for((i=0;i<=$2;i++))
do
find "$1" -type f -print0 | head -z -n 1 | xargs -0 -I {} rm -- {}
done