Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid string splitting when transmitting arguments over ssh

To start a distributed computation, I've written a run script that uses ssh to login to a remote machine and start a script that it reads from stdin. However, this run script needs to correctly transmit the user-provided arguments from $@ to the remote machine. However, I noticed that the arguments aren't transmitted correctly.

Let's say, the script task.sh that the remote machine should execute is

i=0
for p in "$@"; do
  echo "#${i}: ${p}"
  i=$((i+1))
done

This script simply iterates over the arguments and prints them line by line, e.g.,

$ bash task.sh hello world 'in one line'
#0: hello
#1: world
#2: in one line

My simplified run script run.sh now looks as follows:

ssh [email protected] "bash -s $@" < task.sh

However, this will print:

$ bash run.sh hello world 'in one line'
#0: hello
#1: world
#2: in
#3: one
#4: line

When I quote $@ with ', i.e.

ssh [email protected] "bash -s '$@'" < task.sh

the following is printed:

$ bash run.sh hello world 'in one line'
#0: hello world in one line

Maybe, it's working when I use an array in run.sh?

ARGS=(bash -s "$@")
ssh [email protected] "${ARGS[@]}" < task.sh

No, it also prints 'in one line' in multiple lines.

Adding additional single quotes around ${ARGS[@]} makes ssh interpret it as a single command and reports: bash: bash -s hello world in one line: command not found.

So, how to properly transmit the arguments to ssh, so they are split correctly? I guess, it probably works with environment variables, but can I also make it work without?

like image 951
Green绿色 Avatar asked Oct 27 '25 14:10

Green绿色


1 Answers

You can use @Q operator :

ssh [email protected] bash -s "${@@Q}" < task.sh
like image 103
Philippe Avatar answered Oct 29 '25 07:10

Philippe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!