2011-08-24 79 views
1

我想運行一個命令使用管道,但接收錯誤:使用反引號中的管道

echo abc | `echo "grep a | grep b"` 
grep: |: No such file or directory 
grep: grep: No such file or directory 
grep: b: No such file or directory 

什麼是錯的代碼?

預期結果是要被執行的以下命令:

echo abc | grep a | grep b 

隨着

abc 
+1

目前還不清楚你的代碼應該完成什麼。請編輯該問題以闡明您希望此代碼執行的操作。 – tripleee

回答

2

目前還不清楚是什麼你正在嘗試做的,但這裏是你在做什麼:

echo "grep a | grep b" 

輸出字符串grep a | grep b

這是反引號的輸出。您正在使用反引號的shell位置需要一個命令,所以「grep'a''|'嘗試使用'grep''b'「作爲命令行,所有的標記字面解釋(我添加了單引號使其更清晰一些),所以shell忽略來自echo的輸入,而是試圖尋找常規表達式a在指定的文件中。您顯然沒有名爲「|」,「grep」或「b」的文件,因此您會收到錯誤消息。

什麼你可能想是

echo abc | grep a | grep b 

其搜索的「a」,從「回聲」的輸出,然後搜索從第一grep的輸出「B」。因爲abc與正則表達式a匹配,所以第一個grep成功,因此匹配行被打印;並且由於它也與正則表達式b相匹配,所以它最終也由grep打印。

爲了擴展這個有點,請嘗試以下操作:

sh$ echo abc; echo bcd; echo xya 
abc 
bcd 
xya 

sh$ (echo abc; echo bcd; echo xya) | grep a # print lines matching a 
abc 
xya 

sh$ (echo abc; echo bcd; echo xya) | grep a | grep b # print lines matching a and b 
abc 

它爲什麼要使用反引號不清晰;如果這不是你想要達到的目標,請詳細解釋你想完成的事情。

如果你想找到匹配A或B線,試試這個:

sh$ (echo abc; echo bcd;) | grep '[ab]' 
+0

不知道爲什麼,但我認爲這是PHP代碼:D我現在刪除了我的答案,因爲它與這個主題無關 – Quamis

0

這部分的結果是錯誤的:

$ `echo "grep a | grep b"` 

由於反引號別不懂管道。嘗試使用相同的替代方法:

$ echo "grep a | grep b" | sh 
+0

它本身並沒有做任何事情。第一個grep將嘗試讀取標準輸入,但標準輸入已經綁定到將命令回顯到管道sh中。 – tripleee

1

只有讓bash解析器看到它時,管道字符纔是特殊的。你用「」引用它,所以它不再是特殊的,grep認爲你希望它從文件|grepb grep字符串a

一般而言,一旦您轉義屬於shell語法一部分的特殊字符,您將無法稍後忽略它(因爲那樣將無法處理實際被稱爲|的文件 - 不是一種好的的想法,但它可能的,並且bash不應該無法處理它。)

將這樣的字符再次視爲特殊的唯一方法是將其重新提交給全新的shell調用口譯員,這是羅伯特馬丁的解決方案。

2

Triplee的解釋是非常接近(如果不是說完全一樣的東西)是什麼,我認爲正在發生的事情。 「Clasic Shell Scripting」[Robbins & Beebe],第7.8.1節,實際上對與我原來的問題有關的疑難解答有很好的解釋。

如果你寫

listpage="ls | more" 
$listpage 

,那麼你從哪裏弄來一個類似的問題 '|' &'more'被視爲ls的參數。給出的理由是,在shell執行變量替換(步驟5/10)的時候,原始輸入已經被分解爲令牌(其中|是1)(步驟1/10)。所以'|'失去其特殊的含義,並被視爲一個論點。

但是,如果你寫:

eval $listpage 

EVAL導致shell在步驟1中,在重新啓動回到 '|'字符被視爲特殊的令牌。