require 'benchmark' => true irb(main):002:0> puts Benchmark.measure { system "xclip-6ren">
gpt4 book ai didi

ruby - 为什么 `xclip .bashrc` 在 ruby​​ 中比系统 ("xclip .bashrc"花费的时间长得多?

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

irb(main):001:0> require 'benchmark'
=> true
irb(main):002:0> puts Benchmark.measure { system "xclip .bashrc" }
0.000000 0.000000 0.000000 ( 0.008030)
=> nil
irb(main):003:0> puts Benchmark.measure { `xclip .bashrc` }
0.000000 0.000000 0.000000 ( 33.215158)
=> nil
irb(main):004:0> RUBY_VERSION
=> "2.0.0"

我已经阅读了互联网上几乎所有关于从 ruby​​ 脚本调用 shell 命令的各种方法的所有内容,但我就是不明白为什么 Kernel#`Kernel 花费的时间长得多#系统

更新:

Kernel#` 仅使用 xclip 时要慢得多。所有其他命令花费的时间几乎相同。

最佳答案

我怀疑 xclip 在您使用反引号进行 shell out 时需要很长时间才能终止。这与选择有关。如果没有通过 -sel 提供的任何选择,它将默认为 XA_PRIMARY,它通常用于通过鼠标中键实现复制和粘贴。

当你运行时

$ xclip text.txt

内容通过 XA_PRIMARY 可用,这意味着您可以通过鼠标中键或 $ xclip -o 粘贴它。当您通过 Ruby 中的 shell 执行它时,它开始变得奇怪:

ruby -e '`xclip text.txt`

如果您什么都不做,它永远不会真正终止。当您在 X11 系统中选择某些内容时它会终止,例如在控制台或其他任何地方。只是选择,用鼠标标记一些东西。如果不这样做,它会在某个时候挂起和/或超时。

当您使用详细模式时,可以观察到相同的行为:

$ xclip -verbose text.txt

Connected to X server.
Using UTF8_STRING.
Reading text.txt...
Waiting for selection requests, Control-C to quit
Waiting for selection request number 1

同样,选择请求会在您选择某些内容时提供。

一个很好的分析工具是 strace (-f 选项也用于跟踪 fork )

$ strace -f ruby -e '`xclip text.txt`'

...
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\20\0\3\0\4\0\200\2INCR", 12}, {NULL, 0}, {"", 0}], 3) = 12
poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "\1\0\f\0\0\0\0\0\235\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 4096, 0, NULL, NULL) = 32
recvfrom(3, 0x165e964, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvfrom(3, 0x165e964, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}], 1, 4294967295

在最后一行它会挂起,直到做出选择。 poll() 用于在文件描述符处等待文件事件。它会在某个时候终止,但 4,294,967,295 毫秒相当长。只需使用 strace -f xclip text.txt 即可对其进行跟踪。

您可以通过ls -l/proc/PID/fd 查看文件描述符。编号为 3 的是 xclip 等待您选择的文件描述符。

调试如此困难的原因是 if 使用 strace xclip text.txt 立即终止,而不是使用 strace -f text.txt。当您想追踪 fork 时,它就不再起作用了。这与使用 Ruby 时遇到的问题相同。它尝试跟踪输出,因为 Kernel#` 想要返回输出。这可能也与机票有关 #9 Not closing stdout when setting clipboard from stdin .

这是我的理论。当你 shell out 并想要跟踪 xclip 的输出时,无论是使用 Ruby 从标准输出读取,还是使用 strace 跟踪 fork ,标准输出都不会在您做出选择之前关闭。

这并不能很好地解释它,但它表明它与 Ruby 没有任何关系。我将创建一个仅关注 xclip 而不是 Ruby 上下文的问题。

关于ruby - 为什么 `xclip .bashrc` 在 ruby​​ 中比系统 ("xclip .bashrc"花费的时间长得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19237559/

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