我希望我的脚本执行其所有整数参数的乘积。我没有执行循环,而是尝试用替换空白*,然后计算操作。但我得到了以下我不明白的结果:
#!/bin/bash
# product.sh
echo $(( ${*// /*} )) # syntax error with ./product.sh 2 3 4
args=$*
echo $(( ${args// /*} )) # ./product.sh 2 3 4 => outputs 24
Run Code Online (Sandbox Code Playgroud)
当使用中间变量工作正常时,第一个会产生错误,这是怎么回事?
M. *_*din 10
第一个错误是如何产生的:
\n来自Bash 参考手册:
\n\n如果参数为 \xe2\x80\x98@\xe2\x80\x99 或 \xe2\x80\x98*\xe2\x80\x99,则依次对每个位置参数应用替换操作
\n
(强调我的)
\n也就是说,表达式${*// /*}替换位置参数内的空格,而不是分隔位置参数的空格。该表达式扩展为2 3 4(在算术上下文中使用时会出现语法错误),因为参数本身不包含空格。尝试用
./product \'2 \' \'3 \' 4\nRun Code Online (Sandbox Code Playgroud)\n你会看到差异。
\n您可以使用IFS:
#!/bin/bash
# product.sh
# set IFS to *
IFS='*'
# use IFS in output
echo "$*"
# perform arithmetic
echo "$(( $* ))";
Run Code Online (Sandbox Code Playgroud)
输出:
2*3*4
24
Run Code Online (Sandbox Code Playgroud)
在您的示例中,该值$*实际上不包含任何文字空格,因此${*// /*}不执行任何操作。
如果确实如此,这些星号将受到通配符扩展的影响,因此即使可行,执行替换的想法似乎也相当脆弱。
我会简单地创建一个函数来处理参数,而不是依赖于替换的技巧——当参数之一是变量等时,这些往往会出现令人讨厌的极端情况。
mul () {
case $# in
[01]) echo "$@";;
*) local n=$1; shift; echo $((n * $(mul "$@")));;
esac
}
Run Code Online (Sandbox Code Playgroud)