在KSH中计算参数中的空白?

时间:2011-01-28 06:09:55

标签: unix ksh

我试图允许将具有空格的字符串计为整个字符串,而不是被解析。这就是我想要发生的事情:

$ ksh program.ksh "what up"
File 'what up' not found.

这就是我得到的:

$ ksh program.ksh "what up"
File 'what' not found.
File 'up' not found.

这是我尝试过的代码:

wflag=false
cflag=false

while getopts "cw" opt; do
  case "$opt" in
    c)
      cflag=true
      ;;
    w)
      wflag=true
      ;;
    /?)
      ;;
  esac
done

问题出在1)当我尝试类似ksh program.ksh "what up"之类的东西时,我会尝试上面的内容,如ksh program.ksh "-w -c"和2)。第二个是最令人困惑的,因为当我打印出wflagcflag时,它们都是真的。这里不应该"-w -c"被视为字符串吗?似乎内核(这是内核在这里工作吗?)正在解析这个,虽然这正是我不想要的;我希望它被视为具有空格的字符串。我已阅读WordSplitting和((关于参数的文章,不会让我发布它)),而认为我理解它。显然,我必须遗漏一些东西,或者毕竟不理解它:P

我的直觉告诉我getopts发生了一些事情,它会自动消除任何空白。我尝试了$(opt)而不是"$opt",以及花括号和/或单引号(我很确定单引号不是可行的)。唉,没有雪茄。

非常感谢任何帮助,感谢您阅读这一文字墙。

1 个答案:

答案 0 :(得分:2)

case语句中的最后一项应该有反斜杠而不是斜杠。为了诊断,让我们做一些其他的改变,这样你就可以看到发生了什么。

#!/bin/ksh
wflag=false
cflag=false

# the first colon means suppress error messages
# the colon after the x means that -x requires an argument
while getopts ":cwx:" opt
do
    echo "opt $opt"
    case "$opt" in
        c)
            cflag=true
            ;;
        w)
            wflag=true
            ;;
        x)
            echo "x is an option, $OPTARG is its argument"
            ;;
        \?)
            echo "invalid option"
            ;;
        *)
            echo "missing argument"
            ;;
    esac
done
echo "cflag $cflag"
echo "wflag $wflag"

现在让我们用几种方式来称呼它:

$ ./script.ksh -c
opt [c]
cflag true
wflag false

精细。

$ ./getoptstest.ksh -c -w
opt [c]
opt [w]
cflag true
wflag true

也没关系。

$ ./getoptstest.ksh -cw
opt [c]
opt [w]
cflag true
wflag true

仍然很好,但我们的答案已经预示。

$ ./getoptstest.ksh '-c -w'
opt [c]
opt [?]
invalid option
opt [?]
invalid option
opt [w]
cflag true
wflag true

现在我们到了某个地方。 Korn shell man页面上写着:

  

领先:在optstring中导致getopts存储字母                 OPTARG中的无效选项,以及将vname设置为?为                 未知选项和:当所需选项参数未命中时                 ING。否则,getopts会输出错误消息。

从最后一个示例之前的示例中可以看出,您可以像-cw一样运行选项。当您传递'-c -w'之类的选项时,getopts会将其视为-c -space ---w。因此,除了两个无效选项(---space)之外,它还会看到-c-w这就是为什么 两者 < / strong>标志正在设置。如果没有前导冒号(这是原始脚本在问题中发布的方式),您应该收到如下错误消息:

./script.ksh: - : unknown option
./script.ksh: --: unknown option

如果仔细观察,你会注意到告密空间和额外的破折号。

令人遗憾的是,man页面没有讨论getopts处理单独传递或聚集在一起的论据的能力。

我不确定我是否了解您的ksh program.ksh "what up"示例是否存在问题。

尝试使用这些选项和参数修改脚本,看看其余部分是如何工作的。

./script.ksh -x
./script.ksh -x foo
./script.ksh -z
./script.ksh -c bar -w

最后一个是棘手的。当找到一个不以破折号开头的参数且前一个选项不接受参数时,getopts将停止处理,其余参数将保留在原位。您可以在shift $(($OPTIND - 1))循环后使用while,然后您就可以通常的方式访问剩余的位置参数。

不幸的是,shell内置getopts无法处理--version等长选项。外部实用程序getopt可以,但在使用它时可能会遇到一些问题。