2

I'm trying to mirror copy the whole directory from one cluster to another cluster right now. But it fails when there is a space in the name and I can't figure out how to solve this problem because it seems scp thinks I'm copying multiple files. I'm using a variable to flag the path that I need so it seems it would not be easily solved by adding a back slash.

This is the code that I'm using:

if ssh user@ip -i key test -d "'$current_dir'"; then echo "Directory exists. Ready to copy $dir_name." scp -i key -r "$current_dir/$dir_name" user@$ip:"$current_dir/$dir_name" else echo Directory doesn\'t exist. Making a new directory. ssh user@$ip -i key mkdir "'$current_dir'" scp -i key -r "$current_dir/$dir_name" user@$ip:"$current_dir/$dir_name" fi 

I have tried single quote, double quotes and single quote with double quotes, but none of them works. Can anyone help me solve it? By the way, the mkdir statement in the code works.

5
  • 1
    What part of this is failing exactly? What is the value of $current_dir? What error are you getting exactly? Commented Nov 24, 2015 at 20:30
  • Hey Etan. The $current_dir is the variable stores the path returned from pwd. And the error says scp ambiguous target. Commented Nov 25, 2015 at 15:35
  • Show the exact error and an exact value for $current_dir that fails. You can use set -x to get the shell to print the exact command it will run out when it runs it. Commented Nov 25, 2015 at 15:37
  • It shows no such file or directory after setting -x, which is reasonable because scp may treat a directory as two file when there is a space in the directory name. Commented Nov 25, 2015 at 16:56
  • You missed the show part of my comment. Show the set -x and exact error output. You may very well need to escape or extra-quote the spaces in the filename so they make it through to scp but without seeing what is happening I can't be sure I even know what the problem is. Commented Nov 25, 2015 at 17:38

3 Answers 3

6

As detailed in this answer, you need to use two sets of quotes, because the filename is interpreted twice: once by the local computer and once by the remote computer.

scp -i key -r "$current_dir/$dir_name" user@$ip:"'$current_dir/$dir_name'" 
Sign up to request clarification or add additional context in comments.

4 Comments

YES, it's successful!!! Thanks miken. I really should figure out how to use stalkoverflow well. Google didn't give me that answer. Anyway, thanks! Happy Thanksgiving.
How does one know what shell is going to be used at the other end in order to know which quoting syntax to apply for the inner quoting? Should this method only be used in scripts where the script's author has control of the shell at the other end?
@codeshot Very good questions, and yes, you really do need to know what shell is running at the other end (though unless it's some abomination like Windows, I think you can assume sh quoting).
@codeshot I don’t know that there are any shells where wrapping an identifier in single quotes won’t insulate spaces from the shell, but – if such a thing existed – then yes: you would have to adjust for that.
-1

You could escape the spaces in your directory name with sed :

current_dir = "/usr/bin/Directory With Spaces" escaped_current_dir = `sed s/ /\\ /g $current_dir` # escaped_current_dir = "/usr/bin/Directory\ With\ Spaces" 

The string with escaped spaces will be read as one string, and one string only, which is what we want.

Comments

-1

You need to set the field separator to a space.

OIFS=$IFS #save the original IFS=$"\ " #set to space current_dir="some dir with spaces" scp_current_dir="some\\ dir\\ with\\ spaces" dir_name="another dir with spaces" scp_dir_name="another\\ dir\\ with\\ spaces" if ssh user@ip -i key test -d $current_dir; then echo "Directory exists. Ready to copy $dir_name." scp -i key -r "$current_dir/$dir_name" user@$ip:"$scp_current_dir/$scp_dir_name" else echo Directory doesn\'t exist. Making a new directory. ssh user@$ip -i key mkdir $current_dir scp -i key -r "$current_dir/$dir_name" user@$ip:"$scp_current_dir/$scp_dir_name" fi IFS=$OIFS #reset it back to the original 

8 Comments

i am wondering why the down vote? was there a problem with the solution? if yes, is there a better solution?
(Not my vote.) How does this help? This sets IFS on the local side but quoting avoids IFS-based splitting entirely. Presumably the remote side has the problem.
Hi Keda. I don't know who did the down vote, but I tried your solution and it didn't work. Still get the same error as scp ambiguous target.
@Jonas is this the entire script that you are using? setting IFS should help with the spaces. if you post the whole script, i can try to see what happened.
@Jonas i fixed the script slightly. now IFS=$"\ ". it may have been the reason it didn't work for you. try it now.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.