Bash:如何在 shift 时使用;在 do..case $1 中

Bash:如何在 shift 时使用;在 do..case $1 中

我正在编写一个 bash 脚本,需要实现“选项”。如何使用 bash 来实现?

我的目标是按照以下方式运行脚本: /myscript.sh -d "/var/log/" -c "test"

我尝试过的:

while shift; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
done

echo "$DIR"
echo "$COMMAND"

答案1

为了扩展@choroba 的答案,这里有一个如何使用的例子getopts

# parse the flag options (and their arguments)
while getopts c:d: OPT; do
    case "$OPT" in
      d)
        DIR="$OPTARG" ;;
      c)
        COMMAND="$OPTARG" ;;
      [?])
        # got invalid option
        echo "Usage: $0 [-d directory] [-c command]" >&2
        exit 1 ;;
    esac
done

# get rid of the just-finished flag arguments
shift $(($OPTIND-1))

请注意,在移出标志参数后,任何“常规”参数都会保留。因此,此时您可以处理它们(例如... for arg in "$@"; do ...),或者如果您的脚本不接受它们,只要在收到任何(if [ $# -gt 0 ]; then echo "Usage ...)时抱怨即可。

答案2

你的错误在于,你在循环顶部进行了移位,在检查第一个参数之前就将其抛出。我认为你可能想表达的是:

#!/bin/bash
while (( "$#" )); do
   case $1 in
      -d)
         shift&&DIR="$1"||die
         ;;
      -c)
         shift&&COMMAND="$1"||die
         ;;
   esac
   shift
done

echo "$DIR"
echo "$COMMAND"

答案3

正如 choroba 所说,获取选项是一个更好的方法。

对于您来说,您可以使用:

getopts c:d: d || die
DIR=$OPTARG
getopts c:d: c || die
COMMAND=$OPTARG

来实现你想用 while 循环做的事情。

字符串c:d:指定可能的开关。冒号表示开关需要一个参数。

您的方法的问题在于,您shift在分析第一个参数之前就进行了调用,并在此过程中将其丢弃。

要修复此问题,请将 while 循环更改为以下内容:

while true; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
        shift || break
done

答案4

通常的方法是使用getopts

相关内容