0

BASH スクリプトを作成し、BASHgetoptコマンドを使用してコマンド ライン引数を解析しています。コマンド ラインで指定された引数を返す代わりに、コマンドに指定されたgetopt引数を返しますgetopt。私が持っているコードは完璧に機能していたので、何が起こっているのかわかりません. getoptsなんらかの理由で、このスクリプトを実行するマシンにインストールされていないため、(余分な「s」を使用して)使用できません。

スクリプトにはコマンド ライン引数が 1 つも指定されていませんが、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 $@"
    eval set -- ${OPTS}
    echo "AFTER $@"
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 "$@"
    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

特にこのコードは 30 分以上前に機能していて、完全に機能しなくなったため、真剣に私を限界に追い込もうとしているので、誰もがこの難問に当てることができる光は非常に高く評価されます!!!

4

1 に答える 1

1

何も問題はありません。私は GNUを(および に BSDを)getoptとしてインストールしているので、このスクリプト ( ) は、変数を設定していますが、あなたのスクリプト ( ) の開始とほぼ同じです。これは多かれ少なかれ、かなり実質的なスクリプトの SSCCE ( Short, Self-Contained, Complete Example ) です。/usr/gnu/bin/getoptgetopt/usr/binchk.getopt.shPROG_NAME

#!/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}" -- "$@")

# 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 $@"
    eval set -- ${OPTS}
    echo "AFTER $@"
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
$

これはすべて正しいように見えます。二重ダッシュの前のオプションは引数から分割されており、二重ダッシュの後のオプションは問題ありません。

したがって、コードに問題があることは明らかではありません。プログラム名として空の文字列を使用しても、問題なく動作しました。

スクリプトのこの部分の出力をマシンに表示する必要がありますか?

于 2013-02-27T04:06:22.863 に答える