![应删除提供的文件数量的脚本仅删除一个文件](https://linux22.com/image/172130/%E5%BA%94%E5%88%A0%E9%99%A4%E6%8F%90%E4%BE%9B%E7%9A%84%E6%96%87%E4%BB%B6%E6%95%B0%E9%87%8F%E7%9A%84%E8%84%9A%E6%9C%AC%E4%BB%85%E5%88%A0%E9%99%A4%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6.png)
我相当原始的 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