2015-09-25 75 views
5

環路我願做這樣的事情:擊與空間

COMMANDS='"ls /" "df ~" "du -hs ~/Devel/"' 
for i in $COMMANDS; do 
    echo $i 
done 

凡結果將是:

ls/
df ~ 
du -hs ~/Devel/ 

但我不能找到空間正確的語法。

回答

8
COMMANDS=("ls /" "df ~" "du -hs ~/Devel/") 
for i in "${COMMANDS[@]}"; do 
    echo "$i" 
done 

這使用數組來存儲命令。此功能也可在ksh,zsh,但不在sh

數組的行爲與"[email protected]"參數數組類似。在"${ARRAY_NAME[@]}"上應用for循環(引號很重要)會連續給你每個項目。如果您省略了引號,則它們將全部一起被淹沒並分割爲IFS環境變量中的分隔符(默認情況下爲'\t','\n'' ')。

+0

這是所問具體問題的正確答案,但正如chepner指出的那樣,這是錯誤路徑上的正確步驟。 –

+0

@GordonDavisson有些人想到他們是否可以在別人考慮他們是否應該這樣做。我傾向於成爲第一種類型。 :D – PSkocik

5

我建議你不要那麼做。首先,它比簡單寫得更長更復雜

ls/
df ~ 
du -hs ~/Devel/ 

其次,扁平字符串不能存儲嵌套的空格分隔的字符串。有沒有辦法(是的,我忽略了eval)來區分在命令中分隔參數的命令和空格的空格。您可以使用簡單的命令的數組,但不能嵌套數組,因此只要您的某個命令的參數包含空格,就會回到原始問題。

commands=("ls /" "df ~" "du -hs ~/Devel") # OK, but... 
commands=("ls \"foo bar\"" "echo 'hello world'") # No. 

如果你希望你的腳本能夠運行由用戶指定的任意命令,把它從一個已知的目錄,而不是源文件(即實現一個插件系統)。

command_dir=~/myscript_plugins 
for f in "$command_dir"; do 
    source "$f" 
done 

其中$command_dir包含要運行的每個命令的一個文件。

或者,定義了一系列的功能,他們的名字存儲在一個字符串(函數名稱不能含有空格,因此沒有必要爲數組):

lister() { ls /; } 
dfer() { df ~; } 
duer() { du -hs ~/Devel; } 

commands="lister dfer duer" 
for command in $commands; do 
    $command 
done 

commands=(lister dfer duer) 
for command in "${commands[@]}"; do 
    $command 
done 

延伸閱讀:I'm trying to put a command in a variable, but the complex cases always fail!

+0

我知道你的答案更正確,但我標記了另一個,因爲它在大多數情況下更簡單和足夠。雖然謝謝! – dargaud