昨天在写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支持的扩展语法啦。