ok I'll bite. I quickly read Ovid's tutorial. Anyhow, I made a solution that combines some of the suggestions in this discussion, and SAFELY uses the shell for truly arbitrary filenames.
Let me know if you can break it, I actually think I got it right (famous last words)
# each filename is wrapped in quotes
# so we only need to escape characters which have
# special meaning to the shell - when it interpolates
# in double-quotes. there are only 4 such characters,
# namely " ` $ and \
# interestingly, newline is NOT one of these...
sub quote_for_shell {
my ($x) = @_;
$x =~ s/([\"\`\$\\])/\\$1/g;
return "\"" . $x . "\"";
}
@command_line = (
quote_for_shell( $prog1 ),
quote_for_shell( $file1 ),
"|",
quote_for_shell( $prog2 ),
"-x -y",
"|",
quote_for_shell( $prog3 ),
">",
quote_for_shell( $file3 )
)
system join " ", @command_line;
I tested this successfully on a randomly generated directory tree full of randomly-generated filenames made up of chr(rand(128)) except "/" and "\0". Actually, $prog1, $file1, etc can have "/" in them because they might be pathnames.