Ruby%x在64位Linux上分叉,但在32位Linux上分叉,并且只使用特定语法

Ruby%x在64位Linux上分叉,但在32位Linux上分叉,并且只使用特定语法,ruby,exec,fork,Ruby,Exec,Fork,下面是一些Ruby代码: puts %x{ pstree #{$$} } # never forks puts %x{ pstree '#{$$}' } # forks on amd64 only 在32位Ubuntu Dapper上,我得到以下输出: t.rb---pstree t.rb---pstree 这对我来说很有意义。但在64位Ubuntu Hardy上,我得到了以下信息: t.rb---sh---pstree t.rb---pstree 这里显示的是,Ruby在其中一种情况

下面是一些Ruby代码:

puts %x{ pstree #{$$} }   # never forks
puts %x{ pstree '#{$$}' } # forks on amd64 only
在32位Ubuntu Dapper上,我得到以下输出:

t.rb---pstree
t.rb---pstree
这对我来说很有意义。但在64位Ubuntu Hardy上,我得到了以下信息:

t.rb---sh---pstree
t.rb---pstree
这里显示的是,Ruby在其中一种情况下会在执行之前分叉。当我将代码放入一个文件并在strace-fF下运行它时,似乎在64位Hardy上它在
execve()
之前调用
clone()
(比如
fork()
),而在32位Dapper上它却没有这样做

我的Ruby版本是:

ruby 1.8.4 (2005-12-24) [i486-linux]
ruby 1.8.6 (2007-09-24 patchlevel 111) [x86_64-linux]

我应该尝试更多地混合和匹配解释器、操作系统和单词大小,但现在这并不容易,因为我不管理这些机器。也许你们中间有人能告诉我64位系统上的这些命令之间有什么区别,更不用说为什么它们在32位系统上工作相同了。

当%x与单个参数一起使用时,Ruby会执行shell扩展(就像您所做的那样)

以下是我对发生了什么的猜测:

Ruby扫描命令以确定是否有任何特殊字符会导致需要执行shell扩展,如果有,它会调用shell来执行扩展。在第二个示例中,单引号足以使Ruby想要调用shell来进行扩展,因此使用fork。在第一个示例中,Ruby可以确定不需要shell扩展,因为命令不包含特殊字符(在变量扩展之后),因此没有fork。这两个版本之间的差异可能与ruby试图确定是否需要shell扩展的内部变化有关。我在32位机器上的ruby 1.8.5上获得了第二个示例的fork

[编辑]

好的,我查看了ruby 1.8.4和1.8.6的源代码,这两个版本使用相同的标准来确定是否调用shell来执行shell扩展,如果命令行中存在以下任何字符,则在提供%x的一个参数时将调用shell:

*?{}[]<>()~&|\\$;'`"\n
这是Ruby用于在两台机器上执行示例中带引号的
pstree
的命令。您应该在32位机器上看到
bash--pstree
,在另一台机器上看到
bash--sh--pstree


所以现在我很好奇,是什么让你发现了这种差异,它导致了一个问题呢?

我通过开发一个具有一系列子进程(fork)的异步处理器来解决这个问题,它发生在主处理器位于前台并收到SIGINT时

我运行:显示“结果是%(怪物延迟作业)”

结果是:“结果是”

  • 是的,我是大师中的“陷阱”符号

Andre

我发现它是因为它在一个Ruby程序中引发了一个问题,该程序将启动另一个程序并使用
pgrep
检查它是否正在运行。这在64位平台上停止正常工作--
pgrep
始终返回某些内容。看来应该归咎于
dash
(Ubuntu Hardy中的新shell);删除引号可以在两种平台上都提供所需的行为。非常感谢。
/bin/sh -c "pstree $$"