2017-04-01 45 views
6

我正在經歷一個Bash tutorial,特別是分詞的主題。字詞分裂在IFS設置爲一個非空白字符在Bash

這個劇本,名爲 「ARGS」,有助於說明詞的拆分實例

#!/usr/bin/env bash 
printf "%d args:" $# 
printf " <%s>" "[email protected]" 
echo 

一個例子:

$ ./args hello world, here is "a string of text!" 
5 args: <hello> <world,> <here> <is> <a string of text!> 

到目前爲止好。我明白這是如何工作的。

但是,當我用非空白字符替換IFS時,請說「:」,如果我直接將字符串作爲參數傳遞,則腳本不會執行單詞分割。

$ ./args one:two:three 
1 args: <one:two:three> 

然而,腳本確實執行字分割到相同的字符串,如果I(1)指定字符串到變量,然後(2)經由參數擴展將字符串傳遞給腳本。

$ IFS=: 
$ variable="one:two:three" 
$ ./args $variable 
3 args: <one> <two> <three> 

爲什麼?具體而言,當IFS未設置且分隔符爲空格字符時,爲什麼將字符串作爲參數傳遞進行單詞拆分?但是,當IFS設置爲非空白字符時,爲什麼不傳遞字符串?

當我使用read而不是此腳本時,相同的字符串也會按預期經歷單詞分割。

$ IFS=: 
$ read a b c 
one:two:three 
$ echo $a $b $c 
one two three 

回答

9

好問題!你可以閱讀更多關於分詞here

殼掃描參數擴展,命令替換 並且沒有爲分詞雙引號內發生算術擴展的結果。

當您通過裸字符串one:two:three與IFS設置爲:參數,猛砸沒有做分詞,因爲裸字符串參數擴展,命令替換,算術擴展上下文之一。

但是,當同一個字符串被分配給一個變量並且該變量被傳遞給未加引號的腳本時,由於它是參數擴展的情況,所以發生分詞。

同樣的道理也適用於這些以及(命令替換):

$ ./args $(echo one:two:three) 
3 args: <one> <two> <three> 

$ ./args "$(echo one:two:three)" 
1 args: <one:two:three> 

由於documentedread命令會做每一行讀詞的拆分,除非IFS已設置爲空字符串。


+1

幹得好,你釘在一個':)' –

+0

我明白參數擴展之後將分詞,按照shell擴展的秩序規則中gnu.org詳述。此外,在您發給我的第一個鏈接中,最後一行顯示「請注意,如果沒有展開,則不會執行分割。」得到它了。那麼,爲什麼當我執行''時,在這個腳本中觸發了_is_分詞。/ args hello world,這裏是「一串文本!」?我沒有明確地進行參數擴展,但是執行了分詞,這意味着觸發了擴展。 –

+1

我看到的唯一的事情是IFS設置爲默認空白字符的裸字符串會觸發單詞分割,但將IFS設置爲非空白字符的純字符串除非通過參數擴展顯式調用,命令替換或類似的擴展。我的猜測是這必須在printf內建方面做得更多,而且我對_that_的工作原理缺乏瞭解。你基本上說過,「如文檔所述,'read'命令在每行讀取時都會進行分詞,除非IFS被設置爲空字符串,看起來printf做了不同的處理。 –

相關問題