通过getopt处理多个标志

时间:2015-02-17 21:25:41

标签: bash

我正在使用一个脚本,应该只使用一个参数来调用每个标志,如下所示:

./testit.sh -n 123 -t tvar -b bvar -s svar my_program.exe flags to my program

其中所有标志只是脚本的标志,脚本将使用标志my_program.exe启动flags to my program。用于执行此操作的简单方法是getopts,如下所示:

#!/bin/bash
# contents of "test_it.sh"
echo "\$* = "$*

getopt_out=`getopt t:T:b:B:s:S:n:N $*`
echo "getopt_out = "$getopt_out

echo "\$* = "$*

set -- `getopt t:T:b:B:s:S:n:N $*`
echo "\$* = "$*

while [ $1 != -- ]; do
  shift
done
shift

echo "**********************************************************************************"
echo "*** The program I want to run is: "$*
echo "**********************************************************************************"

其中(正确)输出为:

**********************************************************************************
*** The program I want to run is: my_program.exe flags to my program
**********************************************************************************

但是,我需要向-n发送多个数字选项,如下所示:

./testit.sh -n 123 456 789 -t tvar -b bvar -s svar my_program.exe flags to my program
输出错误的

**********************************************************************************
*** The program I want to run is: 456 789 my_program.exe flags to my program
**********************************************************************************

我怎样才能从'testit.sh'中删除那些额外的数字?我能够在脚本的开头处理它们(记录它们的值),以便不再需要它们。由于testit.sh脚本依赖于shift,有没有办法让我完全忽略(抛出)数值而不会弄乱命令流,这样shift仍然可以用吗?

编辑:在进一步调查我的原始脚本后,我注意到getopts的输出与我在最小示例中发布的输出不同。我已经在答案中更新了最小的示例以及建议的解决方法,但我会感谢其他(可能更规范和/或更正确)的方法来处理这个问题。)

1 个答案:

答案 0 :(得分:0)

原来的脚本导致我实际使用了POSIXLY_CORRECT=1的问题,这稍微改变了输出中--的顺序。我已经为所有感兴趣的人发布了新代码(包括POSIXLY_CORRECT=1)以及我的解决方法:

#!/bin/sh
echo "\$* = "$*

POSIXLY_CORRECT=1
export POSIXLY_CORRECT

getopt_out=`getopt t:T:b:B:s:S:n:N: $*`
echo "getopt_out = "$getopt_out

set -- `getopt t:T:b:B:s:S:n:N: $*`
echo "\$* = "$*

double_dash_too_soon=false
while [ $1 != -- ]; do
  echo "\$1 = "$1
  case $1 in
    -t) 
      # process this flag
      shift
      ;;  
    -b) 
      # process this flag
      shift
      ;;  
    -s) 
      # process this flag
      shift
      ;;  
    -n) 
      This_num=$2
      echo "This_num = "$This_num
      shift
      while [[ $2 != "-"[a-z,A-Z] ]] ; do
        echo "Dealing with number!"
        if [[ $1 == "--" ]]; then
          echo "WARNING: '--' encountered during numeric reads!!" >&2
          double_dash_too_soon=true
        fi  
        shift
      done
      ;;  
  esac
  shift

  if [ "$double_dash_too_soon" == true ]; then
    double_dash_too_soon=false
    echo "(1) \$* -> "$*
    set -- `getopt t:T:b:B:s:S:n:N $*`
    echo "(2) \$* -> "$*
  fi  

done
shift

echo "**********************************************************************************"
echo "*** The program I want to run is: "$*
echo "**********************************************************************************"