Prevent ssh from breaking shell script parameters

I have a script that is essentially a wrapper around an executable with the same name on another machine. For an example, I will wrap printf here. My current script is as follows:

#!/bin/bash ssh user@hostname.tld. printf " $@ " 

Unfortunately, this is interrupted when one of the arguments contains a space, for example. I would expect the following commands to get identical outputs:

 ~$ ./wrap_printf "%s_%s" "hello world" "1" hello_world1_ ~$ printf "%s_%s" "hello world" "1" hello world_1 

The problem gets even worse when (escaped) newline characters are involved. How could I escape my arguments here?

+6
source share
4 answers
 #!/bin/sh QUOTE_ARGS='' for ARG in " $@ " do QUOTE_ARGS="${QUOTE_ARGS} '${ARG}'" done ssh user@hostname.tld. "${QUOTE_ARGS}" 

This works for spaces. This does not work if the argument has an inline single quote.

+5
source

Based on Peter Lyon's answer, but also allow quotation marks inside arguments:

 #!/bin/bash QUOTE_ARGS='' for ARG in " $@ " do ARG=$(printf "%q" "$ARG") QUOTE_ARGS="${QUOTE_ARGS} $ARG" done ssh user@hostname.tld. "printf ${QUOTE_ARGS}" 

This works for everything I've tested so far, except for the newline:

 $ /tmp/wrap_printf "[-%s-]" "hello'\$t\"" [-hello'$t"-] 
+7
source

Obtaining the right to cite is quite difficult, and it is almost impossible to do it in bash (in general and reliable form).

Use Perl:

 #!/usr/bin/perl use Net::OpenSSH; my $ssh = Net::OpenSSH->new(' user@hostname '); $ssh->system('printf', @ARGV); 
+2
source

Based on answers from Koert and Peter Lyons, here is a wrapper for ssh; I call it "sshsystem". (also available at https://gist.github.com/4672115 )

 #!/bin/bash # quote command in ssh call to prevent remote side from expanding any arguments # uses bash printf %q for quoting - no idea how compatible this is with other shells. # http://stackoverflow.com/questions/6592376/prevent-ssh-from-breaking-up-shell-script-parameters sshargs=() while (( $# > 0 )); do case "$1" in -[1246AaCfgKkMNnqsTtVvXxYy]) # simple argument sshargs+=("$1") shift ;; -[bcDeFIiLlmOopRSWw]) # argument with parameter sshargs+=("$1") shift if (( $# == 0 )); then echo "missing second part of long argument" >&2 exit 99 fi sshargs+=("$1") shift ;; -[bcDeFIiLlmOopRSWw]*) # argument with parameter appended without space sshargs+=("$1") shift ;; --) # end of arguments sshargs+=("$1") shift break ;; -*) echo "unrecognized argument: '$1'" >&2 exit 99 ;; *) # end of arguments break ;; esac done # user@host sshargs+=("$1") shift # command - quote if (( $# > 0 )); then # no need to make COMMAND an array - ssh will merge it anyway COMMAND= while (( $# > 0 )); do arg=$(printf "%q" "$1") COMMAND="${COMMAND} ${arg}" shift done sshargs+=("${COMMAND}") fi exec ssh "${sshargs[@]}" 
0
source

Source: https://habr.com/ru/post/892103/


All Articles