【问题标题】:Mixing "nounset" with "$@" in ksh在 ksh 中混合“名词集”和“$@”
【发布时间】:2016-05-10 04:41:09
【问题描述】:

我有一个脚本需要将其所有参数转发到另一个程序。此外,出于清洁目的,我保持 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>

顺便提一下,bash 下的nounset 处理空的$@ 时不会出错,但此脚本的环境没有bash 作为选项。


有没有办法让 ksh 与空的 $@ 配合得很好?
理想情况下,我希望 "$@" 扩展到零参数,就像 bashksh 在未启用 nounset 时所做的那样。

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

  1. 将目标命令包装在if (( $# &gt; 0 )) 中并有条件地传递$@。我不喜欢这个选项,因为必须始终传递其他常量参数,这会导致重复代码。
  2. 当我需要访问$@ 时,随时切换nounset 选项。这感觉像是一种不好的做法,并违背了启用 nounset 的初衷。

【问题讨论】:

  • 脚本运行后,您无需保持nounset 选项处于活动状态。如果需要修改脚本重新调试,可以重新加进去。这听起来像是“医生,医生,我用锤子敲头疼”的案例——处方是一样的:“别再用锤子敲你的头了”。如果您依赖于设置的环境变量,或者从配置文件中读取,那么您可以明确检查那些重要的。或者,您可以按照您的建议关闭调用其他程序的脚本部分的选项。我不会测试$#
  • @JonathanLeffler - 这就像告诉 Perl 用户删除 use warningsuse strict 如果脚本没有抛出错误。我不想禁用安全功能,我只想在访问$# == 0$@ 时抑制误报情况。
  • IMNSHO,我不同意与 Perl 警告/限制的比较——我从未发现 nounset 有任何相关性(好吧,在过去 30 年或这么多年的shell脚本)。但是,您可以简单地在使用"$@" 的地方关闭nounset。我认为如果你不能切换到 Bash,那将是最干净的,你说你不能这样做。
  • @Mr.Llama、use warningsuse strict 实际上设计得很好,就像 Perl 中的任何东西一样。这绝对不是set -e 的情况(这会产生比它解决的更多的意外、歧义和跨版本不兼容问题),并且有理由证明set -o nounset 的情况并非如此要么。

标签: shell ksh


【解决方案1】:

当您保留set -o nounset 时,将特殊处理保留在一个地方:一个函数。

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

【讨论】:

    【解决方案2】:
    printf "${@:-}"
    

    变量后的冒号允许指定默认值。在KSH variable substitutions 上查看更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-02
      • 2011-11-26
      • 1970-01-01
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多