【问题标题】:Getopts in bash script with sub-arguments带有子参数的 bash 脚本中的 Getopts
【发布时间】:2021-06-09 16:08:25
【问题描述】:

我希望能够运行这样的脚本(带有子参数): 我需要能够使用短选项和长选项

./myscript.sh -u myname --delete-config --delete-data

./myscript.sh -a myname ..........................

./myscript.sh -h

其实我有:


OPTS=`getopt -o a?d:h?dd?dc? --long apps,delete:,delete-data,delete-config -n 'parse-options' -- "$@"`

if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi

eval set -- "$OPTS"


while true; do
  case "$1" in
    -a | --apps ) 
        showHelp
        exit 0
        ;;
    -d | --delete ) 
        username="$2"
        echo $username
        shift 2
        echo "$1"
        echo "$2"
       
        # Here i can add argument to the command

        case "$1" in
            -dd | --delete-data ) 
                deleteData
                shift 1
                ;;
            -dc | --delete-config ) 
                deleteConfig
                shift 1
                ;;   
            * ) echo "Unexpected option: $1 - this should not happen."
                showHelp 
                break 
                ;;
        esac
        ;;
    -h | --help ) 
        showHelp 
        break 
        ;;
    -- ) shift; 
        break 
        ;;    
    * ) echo "Unexpected option: $1 - this should not happen."
        showHelp 
        break 
        ;;
  esac
done

脚本的结果是:

--delete toto --delete-data --delete-config

toto

--删除数据

--删除配置

抑制数据

意外选项:--delete-config - 这不应该发生。

我不明白我在使用 shift 和 getopts 时做错了什么

【问题讨论】:

  • 它是否接受带有双连字符的子参数?我猜最后一个 *) 打印错误消息。
  • 我可以产生最后一个子参数有效但第一个子参数无效的情况在删除 - > shift 3
  • 在这行之后你需要一个while 循环:# Here i can add argument to the command
  • @Philippe 将您的解决方案用于回答(如果需要,可以在您这边测试此脚本没有问题)
  • @Philippe 只有一个循环,它会启动两个脚本,但会抛出错误:suppress en cours data suppress en cours config 意外选项:--delete-config - 这不应该发生。

标签: linux bash getopt getopts


【解决方案1】:

版本略有不同:

#!/usr/bin/env bash

OPTS=`getopt -o a?d:h?dd?dc? --long apps,delete:,delete-data,delete-config -n 'parse-options' -- "$@"`

if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi

eval set -- "$OPTS"


while test "$1" != --; do
  case "$1" in
    -a | --apps )
        showHelp
        exit 0
        ;;
    -d | --delete )
        username="$2"
        echo $username
        shift 2
        echo "$1"
        echo "$2"

        # Here i can add argument to the command

        while test "$1" != --; do
            case "$1" in
                -dd | --delete-data )
                    echo deleteData
                    shift 1
                    ;;
                -dc | --delete-config )
                    echo deleteConfig
                    shift 1
                    ;;
                * ) echo "Unexpected option: $1 - this should not happen."
                    showHelp
                    break
                    ;;
            esac
        done
        ;;
    -h | --help )
        showHelp
        break
        ;;
    -- ) shift;
        break
        ;;
    * ) echo "Unexpected option: $1 - this should not happen."
        showHelp
        break
        ;;
  esac
done

【讨论】:

  • 我确认您的版本有效,而不是我的。我的只是在处理我的情况,而不是使用第三个子参数,你是的。谢谢!
【解决方案2】:

不起作用的解决方案,它仅适用于这种情况,不适用于 3 个子参数

感谢 Philippe 的评论: 让我知道您是否认为这不好,或者目的更好并确认为答案:)

OPTS=`getopt -o a?d:h?dd?dc? --long apps,delete:,delete-data,delete-config -n 'parse-options' -- "$@"`

if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi

eval set -- "$OPTS"


while true; do
  case "$1" in
    -a | --apps ) 
        showHelp
        exit 0
        ;;
    -d | --delete ) 
        username="$2"
        echo $username
        shift 2
        echo "$1"
        echo "$2"
        echo "$3"
        while true; do
        case "$1" in
            -dd | --delete-data ) 
                deleteData
                shift 
                ;;
            -dc | --delete-config ) 
                deleteConfig
                shift
                break
                ;;   
            * ) echo "Unexpected option: $1 - this should not happen."
                showHelp 
                break 
                ;;
        esac
        done
        ;;
    -h | --help ) 
        showHelp 
        break 
        ;;
    -- ) shift; 
        break 
        ;;    
    * ) echo "Unexpected option: $1 - this should not happen."
        showHelp 
        break 
        ;;
  esac
done

【讨论】:

  • 无效的解决方案,仅在这种情况下有效,不适用于 3 个子参数