2013-02-27 144 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 
$ 

這一切看起來是正確的;雙短劃線之前的選項已經從它們的參數中分離出來,雙短劃線之後的選項是正確的。

因此,代碼存在問題並不明顯。即使使用空字符串作爲程序名稱,它對我來說也可以。

可能你應該在機器上顯示這麼多腳本的輸出嗎?