簡體   English   中英

傳遞命令行參數和命令行參數

[英]Pass command line arguments and command line argument

我希望我的腳本像這樣被調用:

./script -f "-a -b "foo bar"" baz

其中-a -b "foo bar"是傳遞給由我的腳本內部執行的命令(例如grep )的命令行參數。

這里的問題當然涉及到引用:天真的方法(將命令行參數擴展為script )將foobar視為單獨的參數,這當然是不希望的。

做到這一點的最佳方法是什么?

沒有真正好的方法可以做到這一點,只有解決方法。 幾乎所有常見的解決方案都涉及將單個參數作為單個參數傳遞,因為另一種選擇-將一個參數列表作為單個參數傳遞-使您每次想要傳遞一個甚至稍微復雜的參數時,都可以繞過大火。會變成事實,這很常見;您的示例只是您將要陷入的元引號混亂的開始。有關更多見解,請參閱Bash FAQ條目

可能最常見的解決方案是將要傳遞的參數放在參數列表的末尾。 這意味着您需要知道實際用於腳本的參數的末尾,這或多或少意味着存在固定數量的位置參數。 通常,固定數字為1。該策略的一個例子是任何腳本解釋器( bash本身, python等)都很好地采用了一個唯一的位置參數,即腳本名稱。 那將使您調用:

./script baz -a -b "foo bar"

這並不總是很方便。 例如, find命令具有-exec選項,其后跟以下參數中的實際命令。 要做到這一點,您必須知道將單詞傳遞到何處。 find通過使用特定的定界符參數來解決該問題:單個分號。 (這是一個任意選擇,但作為腳本參數很少見,因此通常可以解決。)在這種情況下,您的調用將類似於:

./script -f -a -b "foo bar" \; baz

; 顯然,需要用引號引起來,因為否則它將終止命令,但這不是一個復雜的引號問題。

可以通過允許用戶顯式指定定界詞來擴展這一范圍:

./script --arguments=--end -a -b "foo bar" --end baz

這是一些類似find的建議的示例代碼:

# Use an array to accumulate the arguments to be passed through
declare -a passthrough=()

while getopts f:xyz opt; do
  case "$opt" in
    f)
       passthrough+=("$OPTARG")
       while [[ ${!OPTIND} != ';' ]]; do
         if ((OPTIND > $#)); then
           echo "Unterminated -f argument" >>/dev/stderr
           exit 1
         fi
         passthrough+=("${!OPTIND}")
         ((++OPTIND))
       done
       ((++OPTIND))
     ;;
    # Handle other options
  esac
done
# Handle positional arguments

# Use the passthrough arguments
grep "${passthrough[@]}" # Other grep arguments

我發現了一種更短的方法,可以將腳本參數作為參數傳遞給命令,並且沒有任何限制:應評估命令。

在您的問題中,以下script將完成您想要的

#!/bin/bash

# Do whatever you want ...
# Just claim that 2nd quoted argument of script should be passed as
# a set of parameters of grep
eval grep $2

然后,您可以使用包含空格的參數調用此script ,以將其傳遞給grep

./script -f "-a -b \"foo bar\"" baz

要么

./script -f '-a -b "foo bar"' baz

瞧! 將使用正確的參數調用grep

grep -a -b "foo bar"

例如,致電

./script -f '-i "system message" /etc/passwd' baz

然后得到正確的輸出

dbus:x:81:81:System message bus:/:/sbin/nologin

暫無
暫無

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

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