2013-02-27 146 views
0

我正在创建BASH脚本并使用BASH getopt命令解析命令行参数。 getopt不是返回在命令行上提供的参数,而是返回提供给getopt命令的参数。我不确定会发生什么,因为我拥有的代码工作得很完美,看起来没有任何问题,它已停止正常工作(并且不,我没有更新任何内容或更改任何代码或环境设置)。我不能使用getopts(带有额外的's'),因为出于某种未知原因,它不会安装在将运行此脚本的计算机上。BASH getopt命令返回自己的参数而不是命令行参数

尽管脚本提供了零个命令行参数,但getopt命令出于某种原因返回了我提供的所有参数,减去-o标志,而不是指示选项结束的预期--值。那我的代码如下:

SHORT_OPTS=":hvso:l:d:n:p:t:" 
LONG_OPTS="help,version,submit-job,output:,library:,job-dir:" 
LONG_OPTS="${LONG_OPTS},num-nodes:,num-procs:,max-time:" 
OPTS=$(getopt -o "${SHORT_OPTS}" -l "${LONG_OPTS}" -a -n "${PROG_NAME}" -- "${@}") 

# Check for invalid command line options and arguments 
if [[ ${?} -ne ${SUCCESS} ]] ; then 
    echo -e "${PROG_NAME}: error: Invalid option or argument\n" >&2 
    usage ; exit ${FAILURE} 
else 
    echo "BEFORE [email protected]" 
    eval set -- ${OPTS} 
    echo "AFTER [email protected]" 
fi 

# Process command line options and their arguments 
while true ; do 
    case "${1}" in 
     -h | --help) 
      # Display script usage information and exit 
      usage ; exit ${SUCCESS} ;; 
     -v | --version) 
      # Display script version information and exit 
      echo "${PROG_NAME} v${PROG_VERSION}" ; exit ${SUCCESS} ;; 
     -s | --submit-job) 
      # Enable automatic submission of the Moab job 
      JOB_AUTO_SUBMIT="${PREF_YES}" ; shift 1 ;; 
     -o | --output) 
      # Set the base name for output file names 
      TARGET="${2}" ; shift 2 ;; 
     -l | --library) 
      # Set the library to use for NWChem atomic configurations 
      NW_LIB="${2}" ; shift 2 ;; 
     -d | --job-dir) 
      # Ensure the specified directory for the Moab job exists 
      if [[ -e "${2}" ]] ; then 
       JOB_WORK_DIR=$(resolvePath "${2}") ; shift 2 
      else 
       echo -e "${PROG_NAME}: error: -d ${2}: No such directory\n" 
       usage ; exit ${FAILURE} 
      fi ;; 
     -n | --num-nodes) 
      # Ensure the number of compute nodes is greater than zero 
      if positiveInt "${2}" ; then 
       JOB_NODES="${2}" ; shift 2 
      else 
       echo -n "${PROG_NAME}: error: -n ${1}: Number of " 
       echo -e "job nodes must be a positive integer\n" 
       usage ; exit ${FAILURE} 
      fi ;; 
     -p | --num-procs) 
      # Ensure the number of processors per node is greater than zero 
      if positiveInt "${2}" ; then 
       JOB_PROCS="${2}" ; shift 2 
      else 
       echo -n "${PROG_NAME}: error: -p ${2}: Number of " 
       echo -e "processors per node must be a positive integer\n" 
       usage ; exit ${FAILURE} 
      fi ;; 
     -t | --max-time) 
      # Ensure the maximum job runtime is in the correct format 
      if [[ "${2}" == [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ]] ; then 
       JOB_MAX_TIME="${2}" ; shift 2 
      else 
       echo -n "${PROG_NAME}: error: -t ${2}: Invalid time " 
       echo -e "format, please use hh:mm:ss format\n" 
       usage ; exit ${FAILURE} 
      fi ;; 
     --) 
      # No more options to process 
      shift ; break ;; 
    esac 
done 

# Check to see if POTCAR and CONTCAR locations were specified 
if [[ ${#} -eq 2 ]] ; then 
    # Regular expressions for identifying POTCAR and CONTCAR files 
    PCAR_REGEX="[Pp][Oo][Tt][Cc][Aa][Rr]" 
    CCAR_REGEX="[Cc][Oo][Nn][Tt][Cc][Aa][Rr]" 

    # Attempt to identify POTCAR and CONTCAR argument ordering 
    if [[ ${1} =~ ${PCAR_REGEX} && ${2} =~ ${CCAR_REGEX} ]] ; then 
     POTCAR="${1}" ; CONTCAR="${2}" ; shift 2 
    else 
     POTCAR="${2}" ; CONTCAR="${1}" ; shift 2 
    fi 
# Accept exactly two or zero command line arguments 
elif [[ ${#} -ne 0 ]] ; then 
    echo "${PROG_NAME}: error: ${#}: Invalid argument count, expected [2|0]" 
    echo "[email protected]" 
    exit ${FAILURE} 
fi 

鉴于此代码,并运行该应用程序,我得到下面的输出:

BEFORE 
AFTER -- :hvso:l:d:n:p:t: -l help,version,submit-job,output:,library:,job-dir:,num-nodes:,num-procs:,max-time: -a -n vasp2nwchem -- 
vasp2nwchem: error: 7: Invalid argument count, expected [2|0] 
:hvso:l:d:n:p:t: -l help,version,submit-job,output:,library:,job-dir:,num-nodes:,num-procs:,max-time: -a -n vasp2nwchem -- 

所以,代码进入代码的while环部分,跳转到最后一种情况,并移出第一个--,将我提供的所有参数留给getopt,减去-o标志。

任何人都可以解决这个难题的任何亮点都将受到极大的重视,因为它真的很想把我送到边缘,特别是因为这个代码功能不亚于几分钟前,现在已经完全停止工作了! !

回答

1

我没有看到任何错误。我有GNU getopt安装为/usr/gnu/bin/getopt(和BSD getopt/usr/bin),所以这个脚本(chk.getopt.sh)几乎等于你的开始,但我确实设置了PROG_NAME变量。这或多或少是SSCCE(Short, Self-Contained, Complete Example)为您的相当大的脚本。

#!/bin/bash 

PROG_NAME=$(basename $0 .sh) 
SHORT_OPTS=":hvso:l:d:n:p:t:" 
LONG_OPTS="help,version,submit-job,output:,library:,job-dir:" 
LONG_OPTS="${LONG_OPTS},num-nodes:,num-procs:,max-time:" 
OPTS=$(/usr/gnu/bin/getopt -o "${SHORT_OPTS}" -l "${LONG_OPTS}" -a -n "${PROG_NAME}" -- "[email protected]") 

# Check for invalid command line options and arguments 
if [[ ${?} -ne ${SUCCESS} ]] ; then 
    echo -e "${PROG_NAME}: error: Invalid option or argument\n" >&2 
    usage ; exit ${FAILURE} 
else 
    echo "BEFORE [email protected]" 
    eval set -- ${OPTS} 
    echo "AFTER [email protected]" 
fi 

当我运行它,这是输出:

$ bash -x chk.getopt.sh -ooutput -nnumber -pperhaps -ppotato -- -o oliphaunt 
++ basename chk.getopt.sh .sh 
+ PROG_NAME=chk.getopt 
+ SHORT_OPTS=:hvso:l:d:n:p:t: 
+ LONG_OPTS=help,version,submit-job,output:,library:,job-dir: 
+ LONG_OPTS=help,version,submit-job,output:,library:,job-dir:,num-nodes:,num-procs:,max-time: 
++ /usr/gnu/bin/getopt -o :hvso:l:d:n:p:t: -l help,version,submit-job,output:,library:,job-dir:,num-nodes:,num-procs:,max-time: -a -n chk.getopt -- -ooutput -nnumber -pperhaps -ppotato -- -o oliphaunt 
+ OPTS=' -o '\''output'\'' -n '\''number'\'' -p '\''perhaps'\'' -p '\''potato'\'' -- '\''-o'\'' '\''oliphaunt'\''' 
+ [[ 0 -ne '' ]] 
+ echo 'BEFORE -ooutput' -nnumber -pperhaps -ppotato -- -o oliphaunt 
BEFORE -ooutput -nnumber -pperhaps -ppotato -- -o oliphaunt 
+ eval set -- -o ''\''output'\''' -n ''\''number'\''' -p ''\''perhaps'\''' -p ''\''potato'\''' -- ''\''-o'\''' ''\''oliphaunt'\''' 
++ set -- -o output -n number -p perhaps -p potato -- -o oliphaunt 
+ echo 'AFTER -o' output -n number -p perhaps -p potato -- -o oliphaunt 
AFTER -o output -n number -p perhaps -p potato -- -o oliphaunt 
$ 

这一切看起来是正确的;双短划线之前的选项已经从它们的参数中分离出来,双短划线之后的选项是正确的。

因此,代码存在问题并不明显。即使使用空字符串作为程序名称,它对我来说也可以。

可能你应该在机器上显示这么多脚本的输出吗?