我想对一组按字典顺序命名的文件(10-09之前的01-09)运行某些操作。我必须使用相当旧版本的FreeBSD(7.3),所以我不能使用像echo {01..30}
或seq -w 1 30
这样的yummies。
我找到的唯一可行解决方案是printf "%02d " {1..30}
。但是,我无法弄清楚为什么我不能使用$1
和$2
而不是1
和30
。当我运行我的脚本(bash ~/myscript.sh 1 30
)时,printf说{1..30}: invalid number
AFAIK,bash中的变量是无类型的,那么怎样才能将整数参数作为整数接受?
答案 0 :(得分:0)
我猜你正在寻找这个伎俩:
#!/bin/bash
s=1
e=30
printf "%02d " $(eval echo {$s..$e})
答案 1 :(得分:0)
Bash支持C风格的循环:
s=1
e=30
for i in ((i=s; i<e; i++)); do printf "%02d " "$i"; done
您尝试的语法不起作用,因为大括号扩展在参数扩展之前发生,所以当shell尝试展开{$1..$2}
时,它仍然字面上 { {1}},而不是{$1..$2}
。
@Kent给出的答案有效,因为{1..30}
回到解析过程的开始。我倾向于建议避免习惯性地使用它,如eval
can introduce hard-to-recognize bugs - 如果你的命令被eval
和sudo
列入白名单,那么$1
, C-style-for-loop示例将安全地失败,而eval示例......则没那么多。
当然,执行权限提升攻击的人可能无法访问您编写的95%的脚本,但剩下的5%可能真的毁掉了一天;遵循良好做法100%的时间避免陷入邋habit的习惯。
因此,如果一个真的想要将一系列数字传递给一个命令,那么安全的做法就是将它们收集到一个数组中:
'$(rm -rf /; echo 1)'
答案 2 :(得分:0)
好的,我终于明白了!
#!/bin/bash
#BSD-only iteration method
#for day in `jot $1 $2`
for ((day=$1; day<$2; day++))
do
echo $(printf %02d $day)
done
我最初想在文件名中使用循环迭代器作为“日”,但现在我看到在我的确切情况下,更容易迭代正常数字(1,2,3等)并将它们处理成字典循环中的那些。在使用jot
时,请记住$1
是数字金额,而$2
是起点。