2013-09-25 82 views
1

我在Bash shell腳本庫中有一個函數,它使用getopts來接受參數。我想在這些參數之一中指定一個Bash命令。然後該函數繼續使用這個存儲的命令來達到某種目的或另一個目的(例如,使用指定爲執行啓動程序的此存儲命令以自動方式生成GNOME桌面啓動程序)。我怎樣才能以一種用戶友好的方式保存命令中的特殊字符(並且,我的意思是,這種方式不需要用戶在指定的命令中轉義特殊字符或執行其他異常困難的操作)?在Bash getopts參數中保留特殊字符

所以,函數的開頭可能擁有一些諸如下列:

OPTIND=1; while getopts ":i:o:" options; do 
    case "${options}" in 
     i) 
      command_1="${OPTARG}" 
      ;; 
     o) 
      fileName_1="${OPTARG}" 
      ;; 
     \?) 
      echo "invalid option -"${OPTARG}"" 
      return 
      ;; 
     :) 
      echo "option -"${OPTARG}" requires an argument" 
      return 
      ;; 
    esac 

的命令被賦予作爲函數的參數可以是一些諸如下列:

echo "hello" | festival --tts 

回答

0

您可以混合使用普遍的說法與getopts的解析:

OPTIND=1 
while :; do 
    case "${!OPTIND}" in 
    --tts) 
     TTS=true 
     ((++OPTIND)) 
     ;; 
    --another-with-arg) 
     ((++OPTIND)) 
     # Perhaps add a check as well if optarg is valid. 
     ANOTHER=${!OPTIND} 
     ((++OPTIND)) 
     ;; 
    *) 
     if getopts ":ai:o:" options; then 
      case "${options}" in 
      i) 
       command_1="${OPTARG}" 
       ;; 
      o) 
       fileName_1="${OPTARG}" 
       ;; 
      \?) 
       echo "invalid option -"${OPTARG}"" 
       return 
       ;; 
      :) 
       echo "option -"${OPTARG}" requires an argument" 
       return 
       ;; 
      esac 
     else 
      return 
     fi 
     ;; 
    esac 
done 

鋁但如果我在這,I wouldn't use getopts at all

0

我的理解是,你希望用戶能夠寫類似:

my_script -i echo "hello" | festival --tts 

,並有-i後的整個序列,包括管道字符,接受作爲參數。

不幸的是,這是不可能的。被調用的腳本沒有什麼魔法可以做,因爲在調用腳本之前已經解析了整個命令行。

當然,用戶可以寫:

my_script -i 'echo "hello" | festival --tts' 

,但是這將需要拼盡全力,如果所需的命令行中包含撇號。

「常用」方法(例如,find實用程序的-exec選項)用於接受命令行參數,直到找到;。當然,;需要轉義,就像任何管道或其他shell元字符一樣。

你可以做的一件事是提供一個單獨的選項,或許-I,它從stdin讀取一行並將其用作命令。對於難以引用的複雜命令行來說,這將會非常方便,但如果公用程序還想將stdin用於某些其他目的,則會有些尷尬。隨着這一點,用戶可以鍵入:

my_script -I file <<"EOF" 
very_complicated_command 'with$x' "$all kinds of punctuation" 2> logfile | even_pipes 
EOF