Issue
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?
Solution
You can use @Q
operator :
ssh [email protected] bash -s "${@@Q}" < task.sh
Answered By - Philippe Answer Checked By - Mildred Charles (WPSolving Admin)