題 Bash:如何在班次時使用; do..case $ 1 in


我正在研究一個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"

4
2018-01-25 14:43


起源


當你嘗試這個時會發生什麼? - Dennis
僅打印-c)案例 - teslasimus


答案:


為了擴展@ 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 ...)。


5
2018-01-25 15:48



getopt是一個外部依賴。原作者只詢問了轉移,而不是getopt。 - heroxbd
@heroxbd getopt 是一個外部命令,但我建議 getopts (注意“s”),這是一個內置的shell。 - Gordon Davisson


你的錯誤就是你在循環的頂端移動,在你檢查它之前拋出第一個參數。這就是我認為你可能意味著的:

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

echo "$DIR"
echo "$COMMAND"

6
2018-01-25 15:54



死? bash不是Perl - glenn jackman
@glennjackman好評。我沒有意識到這是一個可能的問題。 (注意OP解釋說投訴是它只打印-c)情況。)我假設 die 可能是別名 - 或者至少,無論它是什麼都與問題無關。 - Nicole Hamilton
對,我評論錯誤的人...... - glenn jackman


正如choroba已經說過的那樣, getopts的 是一種更好的方法。

在您的情況下,您可以使用:

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

2
2018-01-25 15:49





通常的方法是使用 getopts


1
2018-01-25 15:08