Rex
Rex copied to clipboard
Error executing commands with space in their full path
Describe the bug
If there's a space in the full path of a command, execution via run() fails with:
[2020-08-19 13:12:48][<local>] ERROR Error executing: /tmp/path with space/hello.
STDOUT:
STDERR:
sh: /tmp/path: No such file or directory at /home/ferki/perl5/perlbrew/perls/ferki/lib/site_perl/5.32.0/Rex/Commands/Run.pm line 326.
This kind of error may be more apparent on Windows, where calling can_run() returns the full path of the executable, which is often under C:\Program Files, which has a space in it.
Without looking into it more closely, it might be a shell quoting issue.
How to reproduce it
Steps to reproduce the behavior:
-
Create a path with space(s) in it
mkdir -p /tmp/path\ with\ space -
Create an executable under that path, e.g. named
hello:#!/bin/bash echo hello -
Run that command with rex:
rex -e 'my $command = "/tmp/path with space/hello"; say run $command'
Shortest code example that demonstrates the bug: see above
Expected behavior
Rex should be able to execute a command even if its full path contains spaces (or possibly other special characters).
Circumstances
- Rex version: 1.12.1
- Perl version: 5.32.0
- OS running rex: Gentoo
- OS managed by rex: local/Gentoo
Debug log
Relevant excerpt is the following:
[2020-08-19 13:29:14][<local>] DEBUG Executing eval-line
[2020-08-19 13:29:14][<local>] DEBUG Executing: export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/pkg/bin:/usr/pkg/sbin ; LC_ALL=C /tmp/path with space/hello
[2020-08-19 13:29:14][<local>] DEBUG ========= ERR ============
[2020-08-19 13:29:14][<local>] DEBUG sh: /tmp/path: No such file or directory
[2020-08-19 13:29:14][<local>] DEBUG ========= ERR ============
TL;DR: users should quote their commands appropriately for now.
Long version:
Thanks to the initial work of @jluis on #1441, we can understand this problem space better by now.
I believe this problem might not be possible to solve reliably in a generic way for all possible combinations of shells and operating systems. Even if it is possible (at least for the interesting subset of the whole problem), it's not simple, and it would be useful to make the solution available more generally than "Rex only" (which would also allow it to be maintained separately from Rex).
Therefore I think it's currently best to say that proper quoting is the duty of the user. Generally speaking, they are in the best position to be aware of the actual details of their own use cases.
The current best idea about the external implementation would be to provide the logic as a quote_command() or similar function, or perhaps even as a new quote-like operator with PerlX::QuoteOperator. It could work best as an external module, like Rex::Commands::ShellQuoter, or perhaps even contributed into Net::OpenSSH::ShellQuoter.
It could look something like:
my $command = 'C:\Program Files\command.exe';
run quote_command($command);
run quote_command($command, target => 'windows');
target could be optional, and may be auto-detected based on the OS of the endpoint where the command is supposed to be run.