|Perl Monk, Perl Meditation|
safely passing args through sshby perl5ever (Pilgrim)
|on Jul 25, 2011 at 06:14 UTC||Need Help??|
perl5ever has asked for the
wisdom of the Perl Monks concerning the following question:
One problem with ssh is that it invokes a shell to exec your remote command and the arguments are re-interpreted via that shell.
For example, let argcount be the following perl script:
Then running argcount 'a b c' returns 1, but running ssh localhost argcount 'a b c' returns 3. Moreover, running ssh localhost argcount 'a;b;c' exhibits even more undesirable behavior.
So, suppose you want to execute a command like perl -e ... that will work as expected even if it executed remotely via ssh. Clearly ... cannot contain any spaces or shell meta-characters. The question is: what's a good way of encoding ... so that it will survive an ssh call?
To be specific about the problem, let backticks() be defined as follows:
The problem is to define a function E() such that all of these give the same results:
Here $x is a perl string containing arbitraty perl source code. Note that the last backticks example likely will preclude any approach which relies on using backslashes to escape meta-characters, although I'm not totally sure about this.
Here's an example of a possible solution:
The idea is to hex-encode the string to ensure that the result doesn't contain any spaces or shell meta-characters.
Are there any other ways of solving this problem?
Update: Note that I am not looking to encode an arbitrary shell command. Another statement of the problem is this:
Given an array ref $invoke_perl which will invoke a perl interpreter via open(..., "-|", @$invoke_perl), and given a scalar $script containing perl source, how do I encode $script (resulting in E($script)) so that:
will pass the arguments ['-e', $script] to the perl interpreter?