在Ruby中使用反引号和管道

时间:2014-04-22 21:18:50

标签: ruby bash piping backticks

在ruby脚本中使用shell命令时会出现此错误。这些命令不会像在bash终端中那样执行。

前两个命令是合理的,第三个不是。

`echo foo` # => "foo\n"
`echo -n foo` # => "foo"
`echo -n foo | cat` # => "-n foo\n"

在bash中,我们会有以下内容:

$ echo foo # => "foo\n"
$ echo -n foo # => "foo"
$ echo -n foo | cat # => "foo"

有没有办法搞砸参数传递给Ruby命令中对echo的调用?如果您不熟悉,命令echo将返回给定的字符串。如果没有-n标记,则会在添加-n时添加换行符,但不会。 cat重复任何给出的内容。

1 个答案:

答案 0 :(得分:7)

首先,Ruby使用/bin/sh而不是bash作为后退操作符。很可能在您的系统上,/bin/sh是指向/bin/bash的链接,但bash在调用sh时的行为有所不同,以便更好地遵守POSIX。然而,正如你的例子所示,它并不完美。 POSIX规范声明echo"不支持任何选项",但是将初始参数-n的处理保留为特定于实现。

/bin/sh作为/bin/bash链接的快速测试中, bash -c "echo -n foo"bash -c "echo -n foo | cat"生成了相同的无换行结果,但sh -c "echo -n foo"sh -c "echo -n foo | cat"显示了您报告的结果。 (我不确定kshdashzsh等其他shell在调用sh时的行为方式如何,但默认情况下它们都会处理-n }作为换行抑制器。)

要获得可预测的结果,请改用printf,除非格式字符串中包含\n,否则永远不会打印换行符。

printf 'foo\n'
printf 'foo'
printf 'foo' | cat

更新:这似乎是bash 3.2中的一个错误,该错误已在4.x系列中的某个位置修复。使用4.1或更高版本时,sh -c "echo -n foo | catsh -c "echo -n foo"会产生相同的输出。