混合" nounset"用" $ @"在ksh

时间:2016-02-01 16:29:54

标签: shell ksh

我有一个脚本需要将其所有参数转发到另一个程序。此外,出于清洁目的,我保持启用shell选项nounset

考虑以下示例脚本:

#!/bin/ksh
set -o nounset

# Pass all of our parameters (plus a few extra) to our target
printf "<%s>\n" "Parameter count: $#" "$@"

只要主调用脚本至少有一个参数,上述工作就可以正常工作。如果它没有参数,则会生成ksh: @: parameter not set并且脚本终止。

$ ./dollar_at.sh "Hello" "World"
<Parameter count: 2>
<Hello>
<World>


$ ./dollar_at.sh ""
<Parameter count: 1>
<>


$ ./dollar_at.sh
./dollar_at.sh[5]: @: parameter not set

如果我禁用nounset选项,我们会收到以下内容:

$ ./dollar_at.sh
<Parameter count: 0>

顺便说一下,nounset下的bash处理空$@没有错误,但此脚本的环境没有bash作为选项。

有没有办法让ksh与空$@玩得很好?
理想情况下,我希望"$@"扩展为零参数,就像bash一样,ksh不启用nounset

到目前为止,我只提出了两种可能的解决方法,我对此都不满意:

  1. if (( $# > 0 ))中包裹目标命令并有条件地通过$@。我不喜欢这个选项,因为必须始终传递其他常量参数,这会导致重复的代码。
  2. 每当我需要访问nounset时,都会切换$@选项。这感觉就像是不好的做法,并且打败了nounset启用的目的。

2 个答案:

答案 0 :(得分:0)

当您保留set -o nounset时,请将特殊处理保留在1个地方:一个功能。

function forwarder {
   target=$1
   shift
   if [ $# -eq 0 ]; then
      "${target}"
   else
      "${target}" "$@"
   fi
}

set -u
forwarder ./dollar_at.sh hello world
forwarder ./dollar_at.sh hello
forwarder ./dollar_at.sh ""
forwarder ./dollar_at.sh

答案 1 :(得分:0)

printf "${@:-}"

变量后冒号允许指定默认值。请参阅KSH variable substitutions