Clear questions and runnable code
get the best and fastest answer
Improve pipe open?by afoken (Canon)
|on Apr 01, 2017 at 15:17 UTC||Need Help??|
A small meditation started by Ssh and qx
Let's face it: qx is evil, as soon as you want to reliably pass arguments to a program. And it's not necessarily perl's fault. Blame the default shell (Update: see The problem of "the" default shell). Luckily, perl has multi-argument pipe open since 5.8.0:
It's so easy. Granted, it takes two more lines than qx, but we got rid of the default shell. And that two extra lines could easily be wrapped in a function:
But, of course, that would be too easy to be true. Why can't we have nice things?
Three-argument pipe open gets the nasty default shell back into play:
Now what? We could resort to my favorite part of perlipc, "Safe pipe opens". 15 to 28 lines of code just to safely start an external program, and all of that only because perl wants to be clever instead of being safe.
How to fix it
Let's make multi-argument pipe open clever.
No! Just no!
So, do we really need to specify the executable twice? We usually don't want to lie to the target program about it's name. It might be useful to make a shell think that it's a login shell, but then again, that can also be done by passing an extra argument. No, we don't want to lie to our child process. If backwards compatibility was not a problem, we could simply disable the shell logic for any pipe open with more than two arguments. But for backwards compatibility, we can't do that. We need is a flag to disable the shell logic.
My first idea was to just double the dash in the MODE argument:
But we still can do better: A single bit is sufficient for a flag. + is already used in MODE, but not in combination with the pipe symbol. So let's use + instead of - to disable the default shell:
Yes, I'm aware that the difference between "+" and "-" in ASCII is two bits.
For a better mnemonic (ls -f uses "*" to indicate an executable file), we could use "*" instead of "-" to disable the default shell and specify the executable file in the third argument:
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)