2010-06-24 62 views
0

如何創建這個小腳本?bash:在所有參數之後存儲所有命令行參數

例如:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc 

我只想要弦,每有一個模式。

-b 
my small string... other things 
-a 
other string 
-c 
any other string ant etc 

任何人都知道如何實現它?

感謝

+0

目前尚不清楚你想要什麼。你是否想要將標誌-a,-b和-c分開,並且在列表中分別擁有一組其他參數?另外,你是否正在尋找一種不使用引號或多個單詞參數的方法? – Slartibartfast 2010-06-24 02:12:39

+0

我想要的是,每當有一個參數(-a或-b或其他)時,腳本在此之後捕獲所有字符串,並將其放入一個變量中,我還需要檢查帶有大小寫或其他模式的參數。我知道如何使這隻有一個參數,但具有多個參數?謝謝。 – fixo2020 2010-06-24 03:05:43

回答

6

這是一個非常簡單的命令行參數循環。命令行參數是$1,$2等,命令行參數的數量是$#。在我們完成之後,shift命令會丟棄這些參數。

#!/bin/bash 

while [[ $# -gt 0 ]]; do 
    case "$1" in 
     -a) echo "option $1, argument: $2"; shift 2;; 
     -b) echo "option $1, argument: $2"; shift 2;; 
     -c) echo "option $1, argument: $2"; shift 2;; 
     -*) echo "unknown option: $1"; shift;; 
     *) echo "$1"; shift;; 
    esac 
done 

UNIX命令通常希望您自己引用多字參數,以便它們顯示爲單個參數。用法如下:

~$ script.sh -b 'my small string... other things' -a 'other string' -c 'any other string ant etc' 
option -b, argument: my small string... other things 
option -a, argument: other string 
option -c, argument: any other string ant etc 

請注意我是如何引用長參數的。

我不建議這樣做,但如果你真的想在命令行多個單詞通過,但把它們作爲單一的參數,你需要的東西多一點複雜:

#!/bin/bash 

while [[ $# -gt 0 ]]; do 
    case "$1" in 
     -a) echo "option: $1"; shift;; 
     -b) echo "option: $1"; shift;; 
     -c) echo "option: $1"; shift;; 

     -*) echo "unknown option: $1"; shift;; 

     *) # Concatenate arguments until we find the next `-x' option. 
      OTHER=() 

      while [[ $# -gt 0 && ! ($1 =~ ^-) ]]; do 
       OTHER+=("$1") 
       shift 
      done 

      echo "${OTHER[@]}" 
    esac 
done 

用法示例:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc 
option: -b 
my small string... other things 
option: -a 
other string 
option: -c 
any other string ant etc 

但是,再次強調這種用法是不被推薦的。它違背了UNIX規範和約定來連接這樣的參數。

+0

謝謝先生,但你的建議是更好的引用或沒有它? – fixo2020 2010-06-24 12:55:02

+0

你可以更具體地瞭解你的程序做什麼,這些選項是什麼? – 2010-06-24 13:00:17

+0

是更新任何社交網絡的客戶端,我想讓它併發,例如,-b更新facebook -t更新twitter -x更新其他社交網絡。 – fixo2020 2010-06-24 13:49:02

0

我看着與getopt這樣做,但我不認爲它能夠;將不帶引號的間隔字符串作爲一個參數處理是非常不尋常的。我認爲你將不得不手動去做;例如:

long_str="" 
for i; do 
    if [ ${i:0:1} = '-' ]; then 
     [ -z "$long_str" ] || echo ${long_str:1} 
     long_str="" 
     echo $i 
    else 
     long_str="$long_str $i" 
    fi 
done 
[ -z "$long_str" ] || echo ${long_str:1} 
0

你應該看看引用傳遞給腳本的參數:

例如:

附件A:

script.sh -a one string here -b another string here 

附件B:

script.sh -a "one string here" -b "another string here" 

和腳本.sh:

echo "$1:$2:$3:$4" 

用Exhibit A,該腳本將顯示:-a:一個:字符串:這裏

用Exhibit B,該腳本將顯示:-a:一個字符串這裏:-b:另一個串這裏

我用冒號分隔東西,使其更加明顯。

在Bash中,如果引用了禁止字符串標記的參數,則強制空格分隔的字符串只是一個標記,而不是許多標記。因爲「$ var」和$ var是兩個,所以你應該引用你在Bash中使用的每個變量,僅用於其值包含標記分隔符(空格,製表符等)的情況。不同的東西,特別是如果var =「帶空格的字符串」。

爲什麼?因爲在一個點上,你可能會想是這樣的:

script.sh -a "a string with -b in it" -b "another string, with -a in it" 

如果你不使用引用參數,而是學嘗試試探法來找到下一個參數是,你的代碼將當它擊中制動假-a和-b令牌。