Using perl system() query with spaces in path variable
Running a local shell and using it to escape your command to be safe for the remote shell would look like this:
system('env', "ssh_addr=$ssh_addr", "remote_dir=$remote_dir", 'bash', '-c',
'printf -v remote_cmd "%q " ls -- "$remote_dir"; ssh "$ssh_addr" "$remote_cmd"');
Unlike just using "'$remote_cmd'"
, the above works with all possible values, including intentionally malicious ones, so long as your remote shell is also bash.
Thanks to @ikegami's answer for demonstrating the use of the end-of-options sigil --
to ensure that even a remote_dir
value that starts with dashes is parsed as a positional argument by ls
String::ShellQuote's shell_quote
is useful in building shell commands.
my $remote_cmd = shell_quote("ls", "--", $remote_dir);
my $local_cmd = shell_quote("ssh", "-i", "id_pub", $ssh_addr, $remote_cmd);
system($local_cmd);
Of course, you can avoid the shell on the local side as follows:
use String::ShellQuote qw( shell_quote );
my $remote_cmd = shell_quote("ls", "--", $remote_dir);
system("ssh", "-i", "id_pub", $ssh_addr, $remote_cmd);
OK you have several possibilities for shell expansion with the way you are doing this.
Firstly is using system() with a string. This will break all your paths on the space characters. you can solve this by using system as a list
system('ssh', '-i', 'id_pub', $ssh_addr, 'ls', $remote_dir)
Now we still have a problem as ssh will run the remote code on the remote server in a shell with shell expansion which will break the path on spaces again
So you need to put $remote_dir inside '
characters to stop the remote shell from breaking up the path: giving
system('ssh', '-i', 'id_pub', $ssh_addr, 'ls', "'$remote_dir'")
Hope this helps/works
Note that as the commenters below have said this makes the assumption that $remote_dir has no '
characters in it. You need to be either escaping or parsing $remote_dir to ensure that you don't get a path that looks like /file.txt'; rm -rf / #
which will attempt to remove every file on the remote system