Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 使用getopt解析负值的参数-有没有让getopt忽略它们的方法?_Bash_Getopt_Command Line Arguments - Fatal编程技术网

Bash 使用getopt解析负值的参数-有没有让getopt忽略它们的方法?

Bash 使用getopt解析负值的参数-有没有让getopt忽略它们的方法?,bash,getopt,command-line-arguments,Bash,Getopt,Command Line Arguments,我使用getopt解析脚本的命令行参数。 所有可选参数(-o和--long)都由getopt处理,但也有强制参数。参数4可以是一个路径或一系列可能为负值的值 script.sh强制/path/one强制/path/two强制/file.txt-200.12,32.7,-18.7 如果参数4以负值开头,则-将触发getopt。显然,这破坏了脚本,因为getopt会抱怨未定义的选项 我可以想到两种变通方法,但都非常粗糙: 在$@上执行sed以使用一些伪字符串替换-,然后在getopt完成解析后执行s

我使用getopt解析脚本的命令行参数。 所有可选参数(-o和--long)都由getopt处理,但也有强制参数。参数4可以是一个路径或一系列可能为负值的值

script.sh强制/path/one强制/path/two强制/file.txt-200.12,32.7,-18.7

如果参数4以负值开头,则
-
将触发getopt。显然,这破坏了脚本,因为getopt会抱怨未定义的选项

我可以想到两种变通方法,但都非常粗糙:

  • 在$@上执行sed以使用一些伪字符串替换
    -
    ,然后在getopt完成解析后执行sed以再次使用
    -
    替换伪字符串
  • 在getopt-1234567890中使用参数定义选项。这将强制参数4拆分为
    -2
    00.12,32.7,-18.7
    ,这两个变量可以组合成一个中间变量。最后,必须再次设置强制参数1-3和4
  • 必须有一个更优雅的方法来做到这一点。Getopt在其他方面做得很好,我想保留它用于命令行解析

    (还有几个选项,我在示例中只提到了-n选项以保持代码块的简短)


    编辑:强制参数4应该保留为$4,因为行中还有进一步的检查。

    有-排序。这里的问题是,
    getopt
    命令除了以连字符开头的选项之外,没有真正理解任何东西,您也无法说服它使用连字符以外的任何东西作为选项的前导。没有办法告诉getopt不要以任何其他方式处理选项

    但是,
    getopt
    不处理参数。它只是将其传递到
    $OPTARG
    变量中,而不进行任何解析。这里有三个选项:

  • 如果您的选项是定位的,则没有理由在此处使用
    getopt
    。只需像往常一样使用
    $1
    $2
    $3
    ,脚本计数和/或格式不正确的数字列表就会失败。如果您愿意,您可以随时计算参数的数量,并将最后一个作为您的列表
  • 另一方面,如果您的选项不是位置的,那么您确实应该考虑赋予数字列表自己的选项,然后专门解释<代码> $opTARG < < /LI>。
  • 如果您所做的非常特殊,请创建您自己的选项解析循环
    getopt
    用于相对简单的任务,有一种方法可以扩展它的用途

  • 上述任何一项都可以在有用的脚本中完成。不过,我鼓励你不要把问题复杂化。脚本应该相对简单,Bash最好用作命令构造和调度语言。我们不是生活在Bash(或者可能只是
    sh
    ?)是发行版中默认唯一可用语言的时代。如果您试图做一些相当复杂的参数处理,您应该强烈地考虑,像Perl、Python或Ruby这样的通用编程语言是否是您要做的更好的选择。

    为使GETOPT停止读取选项,您可以使用“-----”。诀窍:它背后的任何选项/参数都不是getoptCan使用的,您能给出一个代码示例吗?我也检查了手册,但不知道如何实施。谢谢你的见解。强制参数是位置参数(arg 1-4)。但是,有8个可选参数。这些由getopt处理,之后
    $#
    为4。我同意,在这里,另一种语言可能是更好的选择,在某个时候可能会用Python重新编写。当这个脚本第一次出现时,出于几个原因,bash不幸是唯一的选择。我以前也去过那里,所以我不是真的在评判你对语言的选择——只是在那里做了一个一般性的陈述。在您的情况下,您可能需要选项1—只需将
    $1
    通过
    $4
    分配给变量,然后在通过getopt解析其余变量之前将其移出。如果可以的话,你真的不应该试图通过getopt解析负数。你可能是对的。这意味着所有可选参数都必须放在强制参数之后。保留在任何地方放置选项的自由是很好的,但如果这不再可能,那就不是世界末日了。主要的问题是语法有点变化,用户会感到困惑。我只是意识到这可能会使事情进一步复杂化。。。有一个特定的可选参数,用于更改脚本的行为。在这种情况下,只需要/允许一个强制参数。在这种情况下,您最好使用两个独立的选项解析循环,具体取决于该可选参数。不要害怕在Bash中重复你自己。编写shell脚本时,几乎总是尽可能简单。
    ARGS=$(echo "$@" | sed -E "s/-([0-9])/%dummy%\1/g")
    set -- "$ARGS"
    ARGS=`getopt -o n -l no-act -n $0 -- "$@"`
    eval set -- "$ARGS"
    while :; do
      case "$1" in
        -n|--no-act)
          norun=1 ;;
        --) 
          shift; break ;;
        *)
          break 
      esac
      shift
    done
    ARGS=$(echo "$@" | sed -E "s/%dummy%([0-9])/-\1/g")
    eval set -- "$ARGS"
    
    ARGS=`getopt -o n1:2:3:4:5:6:7:8:9:0: -l no-act -n $0 -- "$@"`
    eval set -- "$ARGS"
    while :; do
      case "$1" in
        -n|--no-act)
          norun=1 ;;
        -1|-2|-3|-4|-5|-6|-7|-8|-9|-0)
          TEMPVAR=$1$2
          shift ;;
        --) 
          shift; break ;;
        *)
          break 
      esac
      shift
    done