如何让帮助脚本(Bash / Python / Ruby / Perl)执行复杂的命令?

时间:2014-11-25 00:02:37

标签: python ruby linux bash perl

请在底部查看我的问题。

这是我希望使用system()

在Perl脚本中执行的命令
zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023

但我收到此错误

mbuffer: warning: error connecting to 10.10.47.47:8023: Connection refused
mbuffer: error: unable to connect to 10.10.47.47:8023
mbuffer: fatal: no output left - nothing to do

这是误导性的,因为我可以在终端中执行命令,并且它可以正常工作。

所以现在我已经变得很有创意,找到解决这个限制的方法。将命令放在文件中并执行

system("ssh localhost /tmp/test");

工作,但必须SSH到localhost并使临时文件不好。需要ssh localhost,否则我会收到同样的错误。

为了避免创建临时文件,我尝试制作一个"解析器文件"

#!/usr/bin/bash
$1 | $2

调用pipe.sh,然后调用Perl

my $a = 'zfs send tank/Test0@snap';
my $b = "mbuffer -4 -O 10.10.47.47:8023";
system("pipe.sh $a $b");

pipe.sh执行zfs | send

我的下一个想法是

my $c = "zfs send tank/Test0\@snap \| mbuffer -4 -O 10.10.47.47:8023";
system("pipe.sh $c");

pipe.sh成为

#!/usr/bin/bash
$@

但是这会将每个视为一个单独的命令。即zfs,然后是send,等等。

问题

我已经没有想法如何在不创建临时文件的情况下执行该命令,这很糟糕,因为tank/Test0实际上是for循环中的变量,因此会导致许多写入。

如果他们能够比Bash更好地处理这个问题,我可以打开执行Ruby或Python脚本而不是调用bash脚本。

更新

如果我来自终端

perl -e'system "bash", "-c", q{zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023}'

然后它可以工作,但在脚本中做同样的事情

system("bash", "-c", q{zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023});

给了我(启用了mbuffer verbose 5)

mbuffer: Verbose = 5
mbuffer: total # of phys pages: 1132576 (pagesize 4096)
mbuffer: default buffer set to 22651 blocks of 4096 bytes
mbuffer: getting address info for 10.10.47.47:8023
mbuffer: warning: error connecting to 10.10.47.47:8023: Connection refused
mbuffer: error: unable to connect to 10.10.47.47:8023
mbuffer: allocating memory for 22651 blocks with 4096 byte (90604 kB total)...
mbuffer: creating semaphores...
mbuffer: opening input...
mbuffer: direct I/O hinting failed for input: Invalid argument
mbuffer: fatal: no output left - nothing to do

更新2

这实际上有效!

system("ssh", "localhost", q{zfs send tank/Test0@snap | mbuffer -4 -v 5 -O 10.10.47.47:8023});

我在启用最详细的情况下出现以下错误,但由于某种原因而起作用。

mbuffer: Verbose = 5
mbuffer: total # of phys pages: 1130435 (pagesize 4096)
mbuffer: default buffer set to 22608 blocks of 4096 bytes
mbuffer: getting address info for 10.10.47.47:8023
mbuffer: successfully connected to 10.10.47.47:8023
mbuffer: set TCP send buffer size to 1048576
mbuffer: allocating memory for 22608 blocks with 4096 byte (90432 kB total)...
mbuffer: creating semaphores...
mbuffer: opening input...
mbuffer: direct I/O hinting failed for input: Invalid argument
mbuffer: direct I/O hinting failed for output to 10.10.47.47:8023: Invalid argument
mbuffer: checking if we have a controlling terminal...
mbuffer: registering signals...
mbuffer: starting threads...
mbuffer: checking output device...
mbuffer: no device on output stream
mbuffer: checking input device...
mbuffer: no device on input stream
mbuffer: outputThread: starting output on 10.10.47.47:8023...
mbuffer: inputThread: starting with threadid 3...
mbuffer: inputThread: last block has 2640 bytes
mbuffer: inputThread: exiting...
mbuffer: outputThread: last block has 2640 bytes
mbuffer: outputThread: syncing 10.10.47.47:8023...
mbuffer: syncing unsupported on 10.10.47.47:8023: omitted.
mbuffer: outputThread: finished - exiting...
mbuffer: waiting for senders...
mbuffer: joining sender for 10.10.47.47:8023

summary: 46.0 KiByte in  0.0 sec - average of 22.9 MiB/s

1 个答案:

答案 0 :(得分:0)

mbuffer开发人员有关于错误的说法

  

关于与I / O提示相关的警告 - 这些警告可以   安全地被忽略了。 mbuffer只是告诉你没有I / O提示   可能。 I / O提示只是给操作系统提示了什么   一种I / O序列即将到来,以便操作系统能够调整它   该特定方案的操作。 I / O提示已实现   大多数操作系统都有所不同......

至于实际问题,Mojo::IOLoop::ForkCallthis模块中的解决方案,它完全符合我的目标。