Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.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
Linux 解析输入参数的困难_Linux_Bash_Shell - Fatal编程技术网

Linux 解析输入参数的困难

Linux 解析输入参数的困难,linux,bash,shell,Linux,Bash,Shell,我的shell的输入应该遵循以下签名 myscript.sh var1 var2[-o var3][-r var4] -o和-r是可选输入,这些选项可以出现在任何位置(var1和var2之间或开始/结束),但是如果指定了var3,var3将始终位于var4之前。此外,var1将位于VAR2之前 #!/bin/bash case "$#" in ([01]) echo "Usage: $0 var1 var2 [-o val3] [-r val4]" >&2; exit 1;; e

我的shell的输入应该遵循以下签名

myscript.sh var1 var2[-o var3][-r var4]

-o和-r是可选输入,这些选项可以出现在任何位置(var1和var2之间或开始/结束),但是如果指定了var3,var3将始终位于var4之前。此外,var1将位于VAR2之前

#!/bin/bash

case "$#" in
([01]) echo "Usage: $0 var1 var2 [-o val3] [-r val4]" >&2; exit 1;;
esac

VAR1="$1"
VAR2="$2" 
VAR3=
VAR4=


while getopts ":o:r:" opt; do
  case $opt in
    o)
     VAR3=$OPTARG
      ;;
    r)
     VAR4=$OPTARG 
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

shift $(( OPTIND - 1 ))


    if [ -z "${VAR3+xxx}" ] && [ -z "${VAR4+xxx}" ];
    then
    echo $1 $2;
    elif [ -z "${VAR3+xxx}" ]; 
    then
    echo $1 $2 $VAR4;
    elif [ -z "${VAR4+xxx}" ];
    then 
    echo $1 $2 $VAR3;
    else
    echo $1 $2 $VAR3 $VAR4;
    fi

如何处理可选参数位于var1和var2之间的情况

您的调用约定正在与“选项和参数优先”的经典调用约定进行斗争。因此,您需要执行以下操作:

case "$#" in
([01]) echo "Usage: $0 var1 var2 [-o val1] [-r val2]" >&2; exit 1;;
esac

VAR1="$1"
VAR2="$2"
shift 2

# Now use your getopts loop...

你也看到了,但这和那个问题不一样。我不明白。。。执行VAR1=“$1”将分配第二个参数。在我的例子中,第二个参数可以是可选参数,我的意思是可选参数可以是任意位置,所以VAR1=$1假设我的非可选参数是第一个。我说得对吗?如果你需要你所要求的极度灵活性,你需要加入GNU
getopt
命令,它可以理解长选项,并且在命令行参数之前排列选项,而不带选项字母。或者写你自己的版本。如果您能坚持“在可选选项之前选择强制选项”,上面的代码将有所帮助。如果你能坚持“在可选选项之后选择强制性选项”,那么你的原始代码就会起作用。将这两种方法交叉使用需要标准(非GNU)版本的
getopt
getopts
不能处理的体操。小心使用
getopt
vs
getopts