gpt4 book ai didi

Ruby %x 在 64 位 Linux 上派生,但在 32 位上没有派生,并且仅使用特定语法

转载 作者:数据小太阳 更新时间:2023-10-29 08:56:05 25 4
gpt4 key购买 nike

这是一些 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 在其中一种情况下在执行前进行 fork 。当我将代码放入文件中并在 strace -fF 下运行时,它似乎在 64 位 Hardy 上调用了 clone()(如 fork()) execve(),而在 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 上获得了第二个示例的分支。

[编辑]

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

*?{}[]<>()~&|\\$;'`"\n

在这两种情况下,Ruby 实际上都在调用 shell(在包含引号的示例中),这就是您在 pstree 中看到不同输出的原因是由于sh的差异命令在不同的机器上,一个调用 fork ,另一个没有。要亲自查看,请在两台计算机上运行此命令:

/bin/sh -c "pstree $$"

这是 Ruby 用来执行 pstree 的命令在两台机器上都带有引号的示例中。你应该看到 bash---pstree在 32 位机器上和 bash---sh---pstree在另一个上。

现在我很好奇,是什么让您发现了这种差异,它是否导致了问题?

关于Ruby %x 在 64 位 Linux 上派生,但在 32 位上没有派生,并且仅使用特定语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/214205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com