How to pipe the content of a variable as STDIN in a qx{} statement in Perl?

后端 未结 3 1791
春和景丽
春和景丽 2021-01-06 07:28

I basically would like to do this:

$_ = \"some content that need to be escaped &>|\\\"$\\\'`\\s\\\\\";
qx{echo $_ | foo}

There are

3条回答
  •  执念已碎
    2021-01-06 08:16

    The following assume @cmd contains the program and its arguments (if any).

    my @cmd = ('foo');
    

    If you want to capture the output, you can use any of the following:

    use String::ShellQuote qw( shell_quote );
    my $cmd1 = shell_quote('printf', '%s', $_);
    my $cmd2 = shell_quote(@cmd);
    my $output = qx{$cmd1 | $cmd2};
    

    use IPC::Run3 qw( run3 );
    run3(\@cmd, \$_, \my $output);
    

    use IPC::Run qw( run );
    run(\@cmd, \$_, \my $output);
    

    If you don't want to capture the output, you can use any of the following:

    use String::ShellQuote qw( shell_quote );
    my $cmd1 = shell_quote('printf', '%s', $_);
    my $cmd2 = shell_quote(@cmd);
    system("$cmd1 | $cmd2");
    

    system('/bin/sh', '-c', 'printf "%s" "$0" | "$@"', $_, @cmd);
    

    use String::ShellQuote qw( shell_quote );
    my $cmd = shell_quote(@cmd);
    open(my $pipe, '|-', $cmd);
    print($pipe $_);
    close($pipe);
    

    open(my $pipe, '|-', '/bin/sh', '-c', '"$@"', 'dummy', @cmd);
    print($pipe $_);
    close($pipe);
    

    use IPC::Run3 qw( run3 );
    run3(\@cmd, \$_);
    

    use IPC::Run qw( run );
    run(\@cmd, \$_);
    

    If you don't want to capture the output, but you don't want to see it either, you can use any of the following:

    use String::ShellQuote qw( shell_quote );
    my $cmd1 = shell_quote('printf', '%s', $_);
    my $cmd2 = shell_quote(@cmd);
    system("$cmd1 | $cmd2 >/dev/null");
    

    system('/bin/sh', '-c', 'printf "%s" "$0" | "$@" >/dev/null', $_, @cmd);
    

    use String::ShellQuote qw( shell_quote );
    my $cmd = shell_quote(@cmd);
    open(my $pipe, '|-', "$cmd >/dev/null");
    print($pipe $_);
    close($pipe);
    

    open(my $pipe, '|-', '/bin/sh', '-c', '"$@" >/dev/null', 'dummy', @cmd);
    print($pipe $_);
    close($pipe);
    

    use IPC::Run3 qw( run3 );
    run3(\@cmd, \$_, \undef);
    

    use IPC::Run qw( run );
    run(\@cmd, \$_, \undef);
    

    Notes:

    • The solutions using printf will impose a limit on the size of the data to pass to the program's STDIN.

    • The solutions using printf are unable to pass a NUL to the program's STDIN.

    • The presented solutions that use IPC::Run3 and IPC::Run don't involve a shell. This avoids problems.

    • You should probably use system and capture from IPC::System::Simple instead of the builtin system and qx to get "free" error checking.

提交回复
热议问题