昨天在寫ruby的過程中發現一個很奇怪的問題。
我們在ruby中調用shell命令,通常使用反括弧(數字鍵1左邊那個)把shell 命令括起來即可,比如:
`ls -l`
這行代碼的輸出是一個字串,既是ls -l命令的返回結果。
但是當shell命令中使用了Process Substitution文法後,悲劇就發生啦。
比如下面這個命令:
cat <(echo Hello)
這個命令先運行小括弧裡面的內容,然後將echo Hello的輸出重新導向到一個檔案中,cat命令顯示這個檔案的內容。<()這種形式是一個典型的Process Substitution。直接在終端輸入上述命令,返回結果是:
Hello
說明上述命令是正確的。
但是在ruby中調用這個命令:
`cat <(echo Hello)`
得到的輸出結果是:
sh: 1: Syntax error: "(" unexpected
提示無法解析命令中小括弧。
我做了另外一個實驗,建立一個Test.sh檔案,裡面寫上同樣的命令
cat <(echo Hello)
然後在終端敲上:
sh Test.sh
得到的同樣是無法解析命令中的小括弧的錯誤提示。
但是當我使用
bash Test.sh
就能得到Hello的正確輸出。
通過Google瞭解到,標準的Shell不支援Process Substitution文法,而bash是支援的。雖然linux下預設使用的是bash,但是ruby中對命令的調用預設使用的是標準shell。
於是問題轉換為如何讓ruby使用bash調用shell命令。
通過man bash查看bash的使用方法,發現bash命令有一個-c參數,可以讓bash運行指定的字串而不是shell檔案。
於是在ruby中使用如下方式:
`bash -c 'cat <(echo Hello)'`
注意-c後面的參數需要使用單引號包起來。
這樣,ruby中也能使用bash調用shell命令啦,再也不用擔心使用到bash支援的擴充文法啦。