【问题标题】:Sh - Get next array elementSh - 获取下一个数组元素
【发布时间】:2012-12-21 10:13:31
【问题描述】:

我的脚本使用的参数是我的两倍:

第一次使用以下代码,以确保没有我不想要的参数(我只考虑 arg1:arg2:arg3)

     PARAM=$@
     while [ "$#" -gt "0" ]; do
              case $1 in
                       arg1)
                                shift2
                                ;;
                       arg2)
                                shift
                                ;;
                       arg3)
                                shift
                                ;;
                       *)
                                echo "Usage : ./test.sh arg1 <VAL1> <VAL2> [arg2] [arg3]"
                                exit 2
                                ;;
              esac
              shift
     done

我想重新解析这些参数,并在我得到 arg1 时能够得到以下两个参数,所以我从这样的东西开始:

     for command in $PARAM
     do
         case $command in
             arg1)
                 shift
                 VALUE1=$command
                 shift
                 VALUE2=$command
                 exec_arg1
                 ;;
         esac
         shift

但在使用“shift”时,我收到错误 shift: can't shift that many

shebang 是“#!/bin/sh”,我正在寻找无需使用 bash 的 shebang(即“#!/bin/bash”)的解决方案

【问题讨论】:

  • @ZackDibe “混合参数位置”到底是什么意思?
  • 什么是shift2?缺少空间?此外,shift 更改 $@ 不是 $command,所以不要分配 $command 而是 $1

标签: linux bash shell sh


【解决方案1】:

您无法将列表连接到字符串并安全地将其转回列表(没有complex helper function)。见this FAQ

shift 在不同的 shell 中表现不同。在 Bash 和 Zsh 中,当没有保留位置参数时,shift 只会返回 false。包括 Dash 在内的许多 shell(与 POSIX 相反,可能是因为 ksh 行为)反而会引发致命错误。 ksh93 通过内置的command 提供了一种解决方法,但这似乎也不是由POSIX 指定的,尽管这个workaroud 无论如何也适用于Dash,但不适用于mksh(我昨天刚刚发现的mksh 中还有一个错误这会阻止它工作,并且维护者可能不会以允许解决方法的方式修复它)。 Busybox 也不遵循 POSIX,也没有给出有意义的退出代码。

无论如何,关键是您不能依赖shift,因为这里有很多shell 存在错误。如果可能的话,您应该迭代参数而不移动它们,并以确保您不会像当前那样移动到边缘的方式测试剩余参数的数量。我认为您预先验证参数的想法并不比同时验证和解析更好。

#!/bin/sh

f()
    if ! ${_called_f+false}; then
        while ! ${1+false}; do
            case $1 in
                arg1)
                    ${3+:} return 1
                    value1=$2 value2=$3
                    shift 3
                    exec_arg1
                    ;;
                arg[23])
                    ${2+:} return 1
                    value1=$1
                    shift
                    "exec_arg${value1##"${value1%?}"}" # Only do this crap if restricted to POSIX
                    ;;
                *)
                    return 1
            esac
        done
    else
        # Hack nobody will understand since this probably isn't what you want anyway.
        _called_f= value1= value2= command eval \
            'typeset +x value{1,2} 2>/dev/null; f "$@"'
    fi

if ! f "$@"; then
    echo 'Error parsing args, exiting...' >&2
    exit 1
fi

另见:option parsing

【讨论】:

    猜你喜欢
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多