2010-08-12 36 views
7

我試着用管道運行命令。如何從變量運行腳本命令?

基本

single="ls -l" 
$single 

預期

它的工作原理:

multi="ls -l | grep e" 
$multi 
ls: |: No such file or directory 
ls: grep: No such file or directory 
ls: e: No such file or directory 

...難怪

bash < $multi 

$multi: ambiguous redirect 

下一個嘗試

bash $multi 
/bin/ls: /bin/ls: cannot execute binary file 

只有

echo $multi > tmp.sh 
bash tmp.sh 

工作。

有沒有辦法執行更復雜的命令,而無需創建腳本執行?

+0

查看[BashFAQ/050](http://mywiki.wooledge.org/BashFAQ/050)。 – 2010-08-12 17:39:43

回答

11

您正在演示shell與內核之間的區別。

「ls -l」可由系統execve()調用執行。詳情請參閱man execve,但這可能對您而言太多了。

「ls -l | grep e」需要shell解釋來設置管道。沒有使用shell,'|'字符只是傳遞給execve()作爲ls的參數。這就是爲什麼你看到「沒有這樣的文件或目錄」錯誤。

解決方案:

cmd="ls -l | grep e" 
bash -c "$cmd" 
+0

謝謝,任何想法爲什麼「bash -c」在一行中打印輸出?我想要有與在命令行手動輸入相同的輸出。 – stacker 2010-08-12 16:27:48

+0

@stacker我不認爲這是真的。我得到了和命令行一樣的結果。也許你的grep只返回一行? – bukzor 2010-08-12 16:33:38

+0

發生這種情況是因爲我忘記用雙引號括起變量。 – stacker 2010-08-12 16:38:33

-3
時要與管道運行命令,只要運行它

。永遠不要將命令放入一個變量並嘗試運行它。如果你想捕捉的輸出簡單地執行它

ls -l |grep

,使用$()

var=$(ls -l |grep ..)

+0

命令來自不同的服務器,應該在目標機器上運行。因此它不能被硬編碼。 – stacker 2010-08-12 16:29:55

+0

見http://mywiki.wooledge.org/BashFAQ/050 – ghostdog74 2010-08-13 00:22:21

0

你需要一個heredoc正確地做到這一點。在回答POSIX compliant way to see if a function is defined in an sh script時,我詳細介紹瞭如何將腳本讀入變量,以編程方式解析它以獲取信息和/或根據需要修改它,然後從另一個腳本或shell函數中執行它。這基本上是你想要做什麼,以及heredoc使得有可能,因爲它提供了一個文件描述符:

% multi='ls -l | grep e' 
% sh <<_EOF_ 
> ${multi} 
> _EOF_ 
< desired output > 

這將解決您的簡單的例子情況。看到我的其他答案更多。

-Mike