3

I want to remove multiple files from remote server. I have all files under one array in a script and I call other script which will remove files.

Let output of "${b[@]}" is:

/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-30-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_05-00-02.tar.gz

script which will remove file is:

#!/bin/bash  
file="$1"  
sshpass -p 'password' ssh user@192.168.3.3 "echo "$file""

while calling bash /tmp/1.sh "'${b[@]}'" I get error

bash: -c: line 0: unexpected EOF while looking for matching `''  
bash: -c: line 1: syntax error: unexpected end of file

And while calling bash /tmp/1.sh "${b[@]}" it assigns only one file to file variable.
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz

Can someone please tell me how to assign value of array containing spaces to file variable in above script.

UPDATE:: It worked by setting declare -a file=("$@") in other script. But what if want to send more parameter rather than only array?

4
sshpass -p 'password' ssh user@192.168.3.3 "some_cmd $(printf '%q ' "$@")"
sshpass -p 'password' ssh user@192.168.3.3 "f() for i; do some_cmd "$i"; done; f $(printf '%q ' some_cmd "$@")"

According to sshpass manpage,

sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments

Therefore you should be able to pass all of "$@" into the ssh command, like:

sshpass -p 'password' ssh user@192.168.3.3 printf '%q\n' "$@"

Since your target command may not be able to handle such argument processing, we can hack this around:

sshpass -p 'password' 'k(){ for i; do echo $i; done; }; k' "$@"

Let's test with some whitespaces...

set -- 'foo bar' $'lorem\nipsum\td'
# paste that two lines.. Since I don't have sshpass installed, just using ssh.

ssh apparently messed up. Let's plug some faked shell in and see what happened..

#!/bin/bash
# /bin/mysh
# someone:x:1000:1000:FOo,,Bar,:/home/foo:/bin/mysh
printf '%q ' bash "$@"; echo;
exec bash -xv --norc "$@";

Hmm. Let's try.

bash -c $'printf %q\\n foo bar lorem\nipsum\td'
printf %q\n foo bar lorem
+ printf %qn foo bar lorem
ipsum   d
+ ipsum d
bash: line 1: ipsum: command not found

So apparently ssh simply concatenated those things together with spaces. Not cool.

Let's pre-escape it on our side with printf '%q ', and you will get the TL; DR answer. Now you can figure out about the EOF and -c failure too.

Note: I am not sure if ssh does the -c thing differently among versions. You may need to try this yourself. At least this is true for OpenSSH 7.1 (ssh.c:955-969).

  • SSH passes a single string to the remote shell. That's how the protocol works. – Gilles Dec 18 '15 at 17:43
  • @Gilles I naively thought by so promising saying command [args...] the thing will properly do some escaping… And it didn't. – Arthur2e5 Dec 18 '15 at 17:45
1

To answer the title of your question:

Passing multiple of arguments with whitespaces through [a script] to ssh

I propose to escape the quotes:

  ssh  user@192.168.3.3  echo "\"arg   1\"    \"arg   2\""

... will send "arg 1" as first argument and "arg 2" as second argument, in this case to the echo command on the remote machine, thus producing the output:

  arg   1 arg   2

NOTE: The command echo outputs the individual arguments with one single blank in between them. However the (multiple) blanks, which are contained in the the individual arguments are preserved. Take this as a proof that the blanks are actually part of the arguments, which was asked for in the title of the question.

0

The first script should be something like:

#!/bin/bash
password="mypassword"
filelist=("$@")

for file in "${filelist[@]}";
do 
    sshpass -p '$password' ssh user@192.168.3.3 "echo \"$file\""
done

The for loop will present each file to the command.


As for the error:

bash: -c: line 0: unexpected EOF while looking for matching `''

I'll assume it ha sto do with the method by which you call the script. You shold be calling it like (one line):

$ ./1.sh "${b[@]}"
  • but again it will create multiple ssh connection which will be expensive..It would be gr8 if in single command we can echo all files. Anyways its working as expected if passed only array as parameter. Check update what if we want to pass multiple parameter. – AVJ Dec 18 '15 at 9:33
  • Again? Where was that requirement ever posted? Yes one connection at a time. – user79743 Dec 18 '15 at 9:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.