Please see my question at the bottom.
This is the command I would like to have executed in a Perl script using system()
zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023
but I get this error
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
which is misleading, as I can execute the command in a terminal, and it works fine.
So now I have become creative to find a way to work around this limitation. Putting the command in a file and do
system("ssh localhost /tmp/test");
works, but having to SSH to localhost and make temp files are not good. The ssh localhost
is needed otherwise I get the same error.
To avoid the temp file creation I tried to make a "parser file"
#!/usr/bin/bash
$1 | $2
which is call pipe.sh
and then in Perl do
my $a = 'zfs send tank/Test0@snap';
my $b = "mbuffer -4 -O 10.10.47.47:8023";
system("pipe.sh $a $b");
but the pipe.sh
executes zfs | send
.
My next idea was
my $c = "zfs send tank/Test0\@snap \| mbuffer -4 -O 10.10.47.47:8023";
system("pipe.sh $c");
with pipe.sh
become
#!/usr/bin/bash
$@
but this treats each as a separate command. I.e. zfs
, then send
and so on.
Question
I have run out of ideas how to execute that command without making a temp file, which is bad, as tank/Test0
is actually a variable inside a for-loop, so it would result in many writes.
Instead of calling a bash script I am open for executing a Ruby or Python script, if they can handle this better than Bash.
Update
If I from the terminal do
perl -e'system "bash", "-c", q{zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023}'
then it works, but doing the same from within the script
system("bash", "-c", q{zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023});
gives me (with mbuffer verbose 5 enabled)
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
Update 2
This actually works!
system("ssh", "localhost", q{zfs send tank/Test0@snap | mbuffer -4 -v 5 -O 10.10.47.47:8023});
I get the following error with the most verbose enabled, but works for some reason.
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