Ruby%x在64位Linux上分叉,但在32位Linux上分叉,并且只使用特定语法
下面是一些Ruby代码: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在其中一种情况
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 $$"