簡體   English   中英

程序參數中帶有參數擴展的奇怪行為

[英]Strange behavior with parameter expansion in program arguments

我試圖僅在調用腳本中設置了參數的情況下才將參數傳遞給bash腳本,並且我注意到某些奇怪的行為。 我正在使用參數擴展來簡化此操作,僅在設置了相應變量的情況下才輸出選項。 目的是將參數從“父”腳本傳遞到“子”腳本。

考慮以下示例:

調用腳本:

#!/bin/bash
# 1.sh

ONE="TEST_ONE"
TWO="TEST_TWO"

./2.sh \
    --one "${ONE}" \
    "${TWO:+"--two ${TWO}"}" \
    --other

和被調用的腳本:

#!/bin/bash
# 2.sh

while [[ $# -gt 0 ]]; do
    key="${1}"

    case $key in
        -o|--one)
        ONE="${2}"
        echo "ONE: ${ONE}"
        shift
        shift
        ;;
        -t|--two)
        TWO="${2}"
        echo "TWO: ${TWO}"
        shift
        shift
        ;;
        -f|--other)
        OTHER=1
        echo "OTHER: ${OTHER}"
        shift
        ;;
        *)
        echo "UNRECOGNISED: ${1}"
        shift
        ;;
    esac
done

輸出:

ONE: TEST_ONE
UNRECOGNISED: --two TEST_TWO
OTHER: 1

觀察選項“ --two”的行為,該行為不會被識別。 看起來好像已正確擴展了該字符串,但並未將其識別為兩個不同的字符串。 誰能解釋為什么會這樣? 我已經看到它是在一個來源中編寫的, it will not work with positional parameter arguments ,但是我仍然不明白為什么這樣做會如此。

這是因為當您從$2 1.sh進行參數擴展時傳遞$2時,您以--two TEST_TWO作為一個單一參數求值的方式1.sh進行引用,從而使2.sh中的參數數改為45

但這就是說,將您的$2用作${TWO:+--two ${TWO}}可以解決此問題,但是如果$2包含空格,則會將其單詞拆分。 您需要使用數組。

作為一種更推薦1.sh方法,請在1.sh上使用以下數組:

argsList=(--one "${ONE}" ${TWO:+--two "${TWO}"} --other)

並將其作為

./2.sh "${argsList[@]}"

或者,如果您熟悉引用規則的工作原理(如何以及何時引用以防止單詞拆分的發生),請在命令行上直接使用它,如下所示。 這樣可以確保內容變量ONETWO即使有空格也可以保留。

./2.sh \
    --one "${ONE}" \
    ${TWO:+--two "${TWO}"} \
    --other

作為一些推薦的准則

  • 始終對用戶定義的變量使用小寫的變量名,以免將它們與外殼程序本身維護的環境變量混淆。
  • 使用getopts()進行更健壯的參數標志解析

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM