Michael Schwarz
2024-Jul-20 11:53 UTC
Proposal: Option to escape/quote individual COMMAND arguments
Hello! IIUC, when I run, $ ssh host cmd arg arg arg the COMMAND (cmd arg...) will be joined locally to a single string like this, "cmd arg arg arg" and then parsed by the shell on the other end. This needs to be taken into account when running commands whose arguments contain spaces. So this won't work: $ ssh host python3 -c "print(1 + 1)" bash: -c: line 1: syntax error near unexpected token `(' bash: -c: line 1: `python3 -c print(1 + 1)' Instead, I can write this to make it work: $ ssh qnap 'python3 -c "print(1 + 1)"' 2 This gets harder to do when some arguments come from somewhere else: $ ssh qnap python3 -c "$script" Or [1]: $ ssh qnap python3 -c "$(<script.py)" When using Bash, I can rewrite the above two commands like this, $ ssh qnap python3 -c "${script at Q}" and like this, $ command=(python3 -c "$(<foo.py)") $ ssh host "${command[@]@Q}" respectively. But it gets complicated quickly. Have there ever been thoughts on automating this step? I propose a new option (-j in the example below) to the ssh command line interface. It takes the arguments of COMMAND and individually escapes them in a way that results in the original words when parsed by a POSIX shell. I.e. it would roughly convert this call $ ssh -j host cmd arg arg arg into this call [2]: $ command=(cmd arg arg arg) $ ssh host "${command[@]@Q}" What do you think? [1]: The $(<filename) is Bash-specific syntax that reads insert's the file's content into the argument list. [2]: See the "Q" operator in Chapter "Shell Parameter Expansion" in the Bash manual. https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html -- Michael they/them, he/him
Marian Beermann
2024-Jul-20 13:49 UTC
Proposal: Option to escape/quote individual COMMAND arguments
This comes up from time to time. The main hurdle is that the ssh client doesn't know what the login shell of the user on the server is, but you need to know that to correctly escape for the shell at hand. (And not all servers are even Unix-like). The real/proper fix is and always would've been a separate request type that's essentially just doing an execvp and simply wouldn't be supported by servers/systems which can't do that (notably Windows). Cheers, Marian On 7/20/24 13:53, Michael Schwarz wrote:> Hello! > > IIUC, when I run, > > $ ssh host cmd arg arg arg > > the COMMAND (cmd arg...) will be joined locally to a single string > like this, > > "cmd arg arg arg" > > and then parsed by the shell on the other end. This needs to be taken > into account when running commands whose arguments contain spaces. > So this won't work: > > $ ssh host python3 -c "print(1 + 1)" > bash: -c: line 1: syntax error near unexpected token `(' > bash: -c: line 1: `python3 -c print(1 + 1)' > > Instead, I can write this to make it work: > > $ ssh qnap 'python3 -c "print(1 + 1)"' > 2 > > This gets harder to do when some arguments come from somewhere else: > > $ ssh qnap python3 -c "$script" > > Or [1]: > > $ ssh qnap python3 -c "$(<script.py)" > > When using Bash, I can rewrite the above two commands like this, > > $ ssh qnap python3 -c "${script at Q}" > > and like this, > > $ command=(python3 -c "$(<foo.py)") > $ ssh host "${command[@]@Q}" > > respectively. > > But it gets complicated quickly. Have there ever been thoughts on > automating this step? > > I propose a new option (-j in the example below) to the ssh command > line interface. It takes the arguments of COMMAND and individually > escapes them in a way that results in the original words when parsed > by a POSIX shell. I.e. it would roughly convert this call > > $ ssh -j host cmd arg arg arg > > into this call [2]: > > $ command=(cmd arg arg arg) > $ ssh host "${command[@]@Q}" > > What do you think? > > [1]: The $(<filename) is Bash-specific syntax that reads insert's > the file's content into the argument list. > [2]: See the "Q" operator in Chapter "Shell Parameter Expansion" > in the Bash manual. > https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html >