2012-07-12 75 views
2

我目前正在修改一個大的BASH腳本,它在幾個不同的發行版(主要是基於Redhat和Debian的版本)上安裝/檢查一系列軟件包。爲什麼在使用eval時awk打印完整行?

爲了解決發行版之間的一些差異(例如rpm vs dpkg,yum vs apt等),我試圖用各種命令字符串加載一些變量,以便腳本沒有充滿if debian then this, otherwise this語句。然而,看起來awk不喜歡被放入一個評估聲明,我不明白爲什麼。

# Example dpkg --list output 
# ii bash  4.1-2ubuntu3 The GNU Bourne Again SHell 

dpkg --list | grep 'bash' 
# Outputs bash entries in dpkg. 

cmd="dpkg --list | grep 'bash'" 
eval $cmd          
# Outputs as expected, same as above. 

dpkg --list | awk '/^.i/ { print $2 }' 
# Outputs as expected, a list of package names. 

cmd="dpkg --list | awk '/^.i/ { print $2 }'" 
eval $cmd 
# Awk prints full output from dpkg for every line matching the regex. 

在上面的代碼,只需grepping給定包工作正常,並如預期打印,而是試圖用awk,該print $2出現生成包名的完整列表時被忽略,只需打印整行。

任何想法?

+3

請參閱[BashFAQ/050](http://mywiki.wooledge.org/BashFAQ/050)。 – 2012-07-12 11:22:57

回答

4

就是這個原因:通過回聲

+0

就是這樣。因爲它是一個雙引號字符串,所以'$ 2'被作爲參數進行評估,而不是直接傳遞給awk。謝謝。 – 2012-07-12 10:02:28

1

eval可能會評估$ 2並將其替換爲它的值試試這個(轉義$ char)。

cmd="dpkg --list | awk '/^.i/ { print \$2 }'" 
+0

創建變量時已經評估了$ 2 – 2012-07-12 09:59:36

1

,看看有什麼殼評估替代的eval你要這個(得逃生:

cmd="dpkg --list | awk '/^.i/ { print $2 }'" 
echo $cmd 

Output: 
dpkg --list | awk '/^.i/ { print }' 

逃離$符號$ in awk script):

cmd="dpkg --list | awk '/^.i.+bash/{ print \$2 }'" 
eval $cmd 

不過我不明白你爲什麼在這種情況下使用eval,它會導致一些問題,在這裏,這 (一個是,你顯然不能使用/^.i.*bash/正則表達式(外殼程序擴展水珠或通過\內的正則表達式),而且還要解決到/^.i.+bash/

0

cmd="dpkg --list | awk '/^.i/ { print \$2 }'" 
+0

給出的例子只是我試圖做的簡化版本。基本上我有很多不同的條件,決定我需要運行哪個命令(各種軟件包管理器檢查等),並保存在我的代碼中放置很多'if ... elif ... else'條件,我只是將所需的命令加載到變量中,使得代碼的其餘部分不可知且更易於使用變量進行維護。 – 2012-07-12 10:48:41