2012-02-03 33 views
1

背景:猛砸表達式求值順序在命令行

我正在呼籲迅速並行SGE的作業提交程序QSUB內bash命令行表達式。雖然這樣做,我試圖提交的表達式(作爲參數)到另一個腳本里面跑出像這樣:

./runArguments.sh的grep FOO跳回到bar.txt> output.txt的

runArguments.sh看起來是這樣的:

#!/bin/bash 
${1} ${2} ${3} etc....to 12 

的想法是,我想要的「grep FOO跳回到bar.txt> output.txt的」腳本進行評估......不是在命令大號INE。在上面的示例中,「grep foo bar.txt」將在runArguments.sh執行過程中進行評估,但輸出重定向將在命令行上進行評估。我最終發現了一個使用「eval」的工作解決方案,如下所示,但我不明白爲什麼它的工作原理。

問題(S)

1)爲什麼

./runArguments.sh eval "grep foo bar.txt > output.txt" 

允許EVAL和表達被視爲參數,但

./runArguments.sh $(grep foo bar.txt > output.txt) 

評估在命令行上在腳本被調用之前? ($(grep ...)的輸出被作爲參數代替)

2)有沒有更好的方法來做到這一點?

在此先感謝!

回答

2

你的第一個問題有點難以回答,因爲你已經自己回答了。如您所見,命令替換($(...)`...`表示法)會替換命令的輸出,然後處理結果。例如,這樣的:

cat $(echo tmp.sh) 

被轉換到這一點:

cat tmp.sh 

所以你的情況,這樣的:

./runArguments.sh $(grep foo bar.txt > output.txt) 

運行grep foo bar.txt > output.txt,抓住它的輸出—這將是什麼,因爲您已將任何輸出重定向到output.txt —並將其替換,產生:

./runArguments.sh 

(所以你的腳本沒有參數運行)。

相比之下,這樣的:

./runArguments.sh eval "grep foo bar.txt > output.txt" 

不執行任何命令替換,所以你的腳本有兩個參數運行:eval,和grep foo bar.txt > output.txt。你的腳本里面這個命令:

${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12} 

因此相同的:

eval grep foo bar.txt '>' output.txt 

其調用eval內置有五個參數:grepfoobar.txt>output.txt。所述eval內置組裝其參數到的命令,並運行它們,甚至平移>output.txt參數爲輸出重定向,因此上述等效於此:

grep foo bar.txt > output.txt 

。 。 。而你已經知道那是做什麼的。 :-)


關於你的第二個問題—沒有,有沒有一個真正的更好的方式來做到這一點。您需要通過>作爲參數,這意味着您需要使用eval ...bash -c "..."等,以便將其「翻譯」回意義輸出重定向。如果你是O.K.與修改腳本,那麼你可能要改變這一行:

${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12} 

這樣:

eval ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12} 

,這樣你就不需要在參數來處理這個問題。或者,其實,你不如改成這樣:

eval ${@} 

這將讓你在超過十二參數傳遞;或者,更好的做法是:

eval "${@}" 

,這將給你過字分裂和fileglobbing和諸如此類的東西稍微更多的控制。

+0

eval $ {@}提示非常有用,謝謝。我仍然不清楚爲什麼在命令輸入期間不評估eval。這有點像操作秩序的概念嗎?例如,bash是否執行1)命令替換2)使用參數執行腳本3)評估eval ...等?運行的程序(RAP)位於[eval sequenceGeek 2012-02-03 02:28:51

+0

@sequenceGeek:在命令輸入過程中,根本沒有理由評估'eval' *。你知道命令'echo cat foo'只是打印文本'cat foo',而不是運行程序'cat'?因爲'echo'是命令,'cat'只是其中一個參數。那麼,'eval'也不例外:它在運行時會有一些有趣的行爲,但是和其他任何命令一樣,只有在它是命令中的第一個單詞時纔會運行。 – ruakh 2012-02-03 03:03:41