I basically would like to do this:
$_ = \"some content that need to be escaped &>|\\\"$\\\'`\\s\\\\\";
qx{echo $_ | foo}
There are
This answer is a very naive approach. It's prone to deadlock. Don't use it!
ikegami explains in a comment below:
If the parent writes enough to the pipe attached to the child's STDIN, and if the child outputs enough to the pipe attached to its STDOUT before it reads from its STDIN, there will be a deadlock. (This can be as little as 4KB on some systems.) The solution involved using something like select, threads, etc. The better solution is to use a tool that has already solved the problem for you (IPC::Run3 or IPC::Run). IPC::Open2 and IPC::Open3 are too low-level to be useful in most circumstances
I'll leave the original answer, but encourage readers to pick the solution from one of the other answers instead.
You can use open2
from IPC::Open2 to read and write to the same process.
Now you don't need to care about escaping anything.
use IPC::Open2;
use FileHandle;
my $writer = FileHandle->new;
my $reader = FileHandle->new;
my $pid = open2( $reader, $writer, 'wc -c' );
# write to the pipe
print $writer 'some content that need to be escaped &>|\"$\'`\s\\';
# tell it you're done
$writer->close;
# read the out of the pipe
my $line = <$reader>;
print $line;
This will print 48
.
Note that you can't use double quotes ""
for the exact input you showed because the number of backslashes \
is wrong.
See perldoc open and perlipc for more information.