【问题标题】:bash pipe doesn't work in ruby #system and doesn't work in ruby Shell#systembash 管道在 ruby​​ #system 中不起作用,在 ruby​​ Shell#system 中不起作用
【发布时间】:2018-07-20 14:31:10
【问题描述】:

我使用以下代码来获取打开的应用程序图标

xprop -notype 32c -id 109051905 _NET_WM_ICON \
                  |    perl -0777 -pe '@_=/\d+/g;
                       printf "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", splice@_,0,2;
                       $_=pack "N*", @_;
                       s/(.)(...)/$2$1/gs' \
                  | convert pam:- /tmp/icon.png

它工作

但是当我在 ruby​​ 中调用上述 bash 时,管道不起作用

system %Q(xprop -notype 32c -id 109051905 _NET_WM_ICON \
                  |    perl -0777 -pe '@_=/\d+/g;
                       printf "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", splice@_,0,2;
                       $_=pack "N*", @_;
                       s/(.)(...)/$2$1/gs' \
                  | convert pam:- /tmp/icon.png)

上升

roroco@roroco ~/Downloads $ ruby /home/roroco/Dropbox/rb/ro_cmds_global/chk/v.rb
convert: negative or zero image size `-' @ error/pnm.c/ReadPNMImage/415.
convert: no images defined `/tmp/icon.png' @ error/convert.c/ConvertImageCommand/3210.

我尝试使用 Shell#system,它仍然不起作用

require 'shell'
sh = Shell.new
sh.system(%Q(xprop -notype 32c -id 109051905 _NET_WM_ICON )) | sh.system(%Q(
                   perl -0777 -pe '@_=/\d+/g;
                       printf "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", splice@_,0,2;
                       $_=pack "N*", @_;
                       s/(.)(...)/$2$1/gs')) |
    sh.system(%Q(convert pam:- /tmp/icon.png))

上升

roroco@roroco ~/Downloads $ ruby /home/roroco/Dropbox/rb/ro_cmds_global/chk/v2.rb
shell(#<Th:0x000000015de228>): /usr/bin/xprop -notype 32c -id 109051905 _NET_WM_ICON
shell(#<Th:0x000000015de228>): /bin/sh -c 
                   perl -0777 -pe '@_=/d+/g;
                       printf "P7
WIDTH %d
HEIGHT %d
DEPTH 4
MAXVAL 255
TUPLTYPE RGB_ALPHA
ENDHDR
", splice@_,0,2;
                       $_=pack "N*", @_;
                       s/(.)(...)/$2$1/gs'
shell(#<Th:0x000000015de228>): /usr/bin/convert pam:- /tmp/icon.png
shell(#<Th:0x000000015de228>): Process finishing, but active shell exists
                               You can use Shell#transact or Shell#check_point for more safe execution.
convert: negative or zero image size `-' @ error/pnm.c/ReadPNMImage/415.
convert: no images defined `/tmp/icon.png' @ error/convert.c/ConvertImageCommand/3210.

那么它如何工作

我找到原因是,使用我使用ruby #system,@_ 在 perl 脚本中为空,所以我认为是 perl 接收输入问题,如何解决?

我可以将 perl 脚本转换为 ruby​​,也许我猜它可以工作,但我想知道为什么 perl 无法在 ruby​​ #system 中接收输入

【问题讨论】:

  • 请提供一个非常简单的说明,说明 perl 无法接收来自 Ruby 的 system 方法的输入。我认为情况并非如此。我建议从一个非常简单的案例开始,逐步建立你的复杂案例,看看它在哪里中断。另外,我想知道您是否可能需要对其中的任何一个进行 shell 转义(使用 Ruby 的 shellwords 模块)。
  • 另外,我认为您的 \n 将作为单个换行符传递给 shell,并且我认为您需要文字反斜杠和 n。您可能需要使用 %q 而不是 %Q。
  • 另外,你不能指望 2 个系统调用相互通信;每个都向操作系统发送外壳,运行命令,等待它完成。如果您需要将一个输出传递给另一个,则需要在对系统的一次调用中指定它们。

标签: ruby linux bash perl


【解决方案1】:

我找到了解决方案,当使用过于复杂的 bash 代码时,我应该使用 %q() 而不是 %Q,下面的代码可以工作:

system %q(xprop -notype 32c -id ) + 111149125.to_s + %q( _NET_WM_ICON \
                  |    perl -0777 -pe '@_=/\d+/g;
                       printf "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", splice@_,0,2;
                       $_=pack "N*", @_;
                       s/(.)(...)/$2$1/gs' \
                  | convert pam:- jpg:-)

【讨论】:

    猜你喜欢
    • 2021-10-28
    • 2021-11-25
    • 1970-01-01
    • 2013-06-12
    • 2023-03-14
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    相关资源
    最近更新 更多