如何在 bash 中将参数设为可选?

αғs*_*нιη 13 bash functions

在下面带有 9 个参数的函数中:

SUM() { 
    echo "The sum is $(($1+$2+$3+$4+$5+$6+$7+$8+$9))"
}
Run Code Online (Sandbox Code Playgroud)

我想让next(3..9)第二个参数成为可选参数

当我用 2 个参数调用函数时,我收到错误:

SUM 3 8
bash: 3+8+++++++: syntax error: operand expected (error token is "+")
Run Code Online (Sandbox Code Playgroud)

注意 BOLD:第一个参数和第二个参数是强制参数,不是函数的可选参数。我只希望下一个的第二个参数是可选的,当我调用小于 2 个参数的函数时,该函数必须不返回任何结果。

mur*_*uru 22

如果您不传递带空格的参数:

sum() {  
[[ -n $2 ]] && echo $(( $(tr ' ' '+' <<<"$@") ))
}
Run Code Online (Sandbox Code Playgroud)

影响:

$ sum 1 2 3
6
Run Code Online (Sandbox Code Playgroud)

解释:

  1. <<<"some string""some string"作为输入输入。将其视为echo "some string" |. 它被称为Here String
  2. "$@"扩展为所有位置参数,以空格分隔。它相当于"$1 $2 ..."
  3. 因此,tr ' ' '+' <<<"$@"输出"$1+$2+$3...",由外部评估$(( ))
  4. [[ -n $2 ]]测试第二个参数是否为非空。你可以[[ -n $2 ]] &&[[ -z $2 ]] ||.

其它的办法:

sum() {
[[ -n $2 ]] && (IFS=+; echo $(( $* )))
}
Run Code Online (Sandbox Code Playgroud)

解释:

  1. $*就像$@,只是参数不是用空格分隔,而是用内部字段分隔符 ( IFS)的第一个字符分隔。使用IFS=+,它扩展为“$1+$2+...”。请参阅$* 和 $@ 之间的区别是什么?
  2. 我们设置IFS了一个子外壳(注意周围的括号),这样主外壳就不会受到影响。IFS默认情况下是:(\t\n空格、制表符、换行符)。这是使用local变量的替代方法。

现在回答你的问题:

您可以为任何变量或参数使用默认值。任何一个:

SUM() { 
 echo "The sum is $(($1+$2+${3:-0}+${4:-0}+${5:-0}+${6:-0}+${7:-0}+${8:-0}+${9:-0}))" || false
}
Run Code Online (Sandbox Code Playgroud)

或者:

SUM() { 
 echo "The sum is $(($1+$2+${3:=0}+${4:=0}+${5:=0}+${6:=0}+${7:=0}+${8:=0}+${9:=0}))" || false
}
Run Code Online (Sandbox Code Playgroud)

  • 漂亮!我知道评论不是为了无偿的赞美和感谢,但这个解决方案只是......邪恶!:-) (6认同)

zwe*_*ets 17

看一下shift运营商。它将把参数 2 和向前移动到位置 1 和向前,丢弃参数 1。

sum () {
    local total=0;
    while [ $# -gt 0 ]; do
        total=$(($total + $1))
        shift
    done
    echo $total
}
Run Code Online (Sandbox Code Playgroud)