Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

IPC::Run / bash pipe

by ag4ve (Monk)
on Nov 06, 2013 at 23:37 UTC ( [id://1061497]=perlquestion: print w/replies, xml ) Need Help??

ag4ve has asked for the wisdom of the Perl Monks concerning the following question:

I'm running up against the pipe buffer doing this:

my $success = run [$echo => -e => "\'" => join("\n", @iptout) => "\'"], '|', [$ipt_cmd => 'iptables-restore'], '>', \my $cmdout, '2>&1';

Error:

exec failed: Argument list too long at ./firewall.pl line 852

So, I figured I'd try this:

my $success = run [$ipt_cmd => 'iptables-restore'], '>', \my $cmdout, '2>&1', '<<<', '${', [$echo => -e => "\'" => join("\n", @iptout) => +"\'"], '}';

Error:

No such file or directory: open( <<, 0x000 ) at ./firewall.pl line 852

But I can't figure out how to get it in proper syntax for IPC::Run? Also, per the limit I'm hitting 'man 7 pipe (I'm running 3.10+ on 64 bit, but this is the latest pipe manpage): In Linux versions before 2.6.11, the capacity of a pipe was the same as the system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11, the pipe capacity is 65536 bytes.

Replies are listed 'Best First'.
Re: IPC::Run / bash pipe
by runrig (Abbot) on Nov 07, 2013 at 00:56 UTC

    What is '<<<' supposed to be?

    Also, I'm not sure what you're trying to accomplish with the quoting, but I don't think you're doing it correctly. If you have the input for your command in a string, then just use it:
    use IPC::Run qw(run); my @arr = qw( abc def ); my $input = join("", map "$_\n", @arr); run [ sed => 's/[ad]/o/' ], "<", \$input, ">", \my $output; print "O: [$output]\n";

    Or compare these various quoting strategies (the first is similar to yours and I believe incorrect, the last is more like what I think you're trying to accomplish):

    use IPC::Run qw(run); my @arr = qw( abc def ); run [ echo => q(') => join("\n", @arr) => q(') ], ">", \my $output; print "O: [$output]\n"; run [ echo => q(') . join("\n", @arr) . q(') ], ">", \my $output; print "O: [$output]\n"; run [ echo => join("\n", @arr) ], ">", \my $output; print "O: [$output]\n";

      This is the syntax I'm going for:

      grep ba > t.txt 2>&1 <<< $(echo -e "foo\nbar\nbaz")

      To demonstrate what I'm Looking at:

      #!/usr/bin/env perl use strict; use warnings; use IPC::Run qw(run); my $str; my $count = 0; while (1) { $count += 10; $str .= "1111111111"; run [echo => $str], '|', [grep => 'foo']; print "$count " unless ($count % 10000) }

      And if you don't feel like waiting for it, here's the result:

      % ./t2.pl 10000 20000 30000 40000 50000 60000 70000 80000 90000 100000 110000 12 +0000 130000 exec failed: Argument list too long at ./t2.pl line 16. at ./t2.pl line 16.

      If I don't use ipset (which are pretty long by their own, I'm under the limit. However, without ipset:

      # wc -c fw2.save 165670 fw2.save

      I don't want to write a tempfile unless there's no other option, ulimit -s unlimited doesn't seem to make a difference, and I'm not sure about FFI::Raw and iptc.o / iptables.o (I'm looking into it).

        Oh, nm, I'm blind (or not paying attention) - that works

        my $success = run [$ipt_cmd => 'iptables-restore'], '<', \(join("\n". @iptout)), '>', \my $cmdout, '2>&1';

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1061497]
Approved by ww
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (2)
As of 2024-04-26 03:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found