How do I escape spaces in path for scp copy in Linux?
Solution 1
Basically you need to escape it twice, because it's escaped locally and then on the remote end.
There are a couple of options you can do (in bash):
scp [email protected]:"'web/tmp/Master File 18 10 13.xls'" .
scp [email protected]:"web/tmp/Master\ File\ 18\ 10\ 13.xls" .
scp [email protected]:web/tmp/Master\\\ File\\\ 18\\\ 10\\\ 13.xls .
Solution 2
works
scp localhost:"f/a\ b\ c" .
scp localhost:'f/a\ b\ c' .
does not work
scp localhost:'f/a b c' .
The reason is that the string is interpreted by the shell before the path is passed to the scp command. So when it gets to the remote the remote is looking for a string with unescaped quotes and it fails
To see this in action, start a shell with the -vx options ie bash -vx
and it will display the interpolated version of the command as it runs it.
Solution 3
Use 3 backslashes to escape spaces in names of directories:
scp user@host:/path/to/directory\\\ with\\\ spaces/file ~/Downloads
should copy to your Downloads
directory the file
from the remote directory called directory with spaces
.
Solution 4
Also you can do something like:
scp foo@bar:"\"apath/with spaces in it/\""
The first level of quotes will be interpreted by scp and then the second level of quotes will preserve the spaces.
Solution 5
I had huge difficulty getting this to work for a shell variable containing a filename with whitespace. For some reason using:
file="foo bar/baz"
scp [email protected]:"'$file'"
as in @Adrian's answer seems to fail.
Turns out that what works best is using a parameter expansion to prepend backslashes to the whitespace as follows:
file="foo bar/baz"
file=${file// /\\ }
scp [email protected]:"$file"
AlexPandiyan
Updated on August 02, 2022Comments
-
AlexPandiyan almost 2 years
I'm new to linux, I want to copy a file from remote to local system... now I'm using scp command in linux system.. I have some folders or files names are with spaces, when I try to copy that file, it shows the error message: "No such file or directory"
I tried:
scp [email protected]:'/home/5105/test/gg/Untitled Folder/a/qy.jpg' /var/www/try/
I saw the some reference online but I don't understand perfectly, can any one help on this?
how can I escape spaces in file name or directory names during copying...
-
Sacrilicious almost 10 yearsThis is pretty minor, but on a Mac and in most console apps like Terminal, there is a 'Paste Escaped Text' option. I therefore used the second option.
-
Hamy over 9 yearsHere is a relevant question: stackoverflow.com/questions/5608112/…
-
troyfolger over 6 yearsI would suggest the more robust 'substitute all' expansion:
file="${file//\ /\\\ }"
-
Luke Davis over 6 yearsForgot about that distinction -- I'm rusty on my parameter expansions. Thanks!
-
Mauricio Trajano over 6 yearsUsing single quotes and escaping worked for me but not double quotes
-
Vorsprung over 6 years@MauricioTrajano take a look at gnu.org/software/bash/manual/html_node/Quoting.html all the quotes do different things. In the simple case above double
"
or single'
work the same -
Michael over 6 yearsThis answer is under-rated, considering how many spaces it can handle with the same amount of escape characters. Thanks!
-
Admin over 6 years' " path " ' worked while " ' path ' " failed; conclusion single quotes first and then the double quotes to surround
-
jankes over 6 yearsWow! That's probably the single most ridiculous program behaviour I've seen!
-
JoL almost 6 years@jankes It isn't without merits. The fact that what you put there is a shell command argument allows you to do stuff like
scp [email protected]:'$(ls -t | head -1)' .
to get the most recently created file in the server, orscp [email protected]:'dir/*.{xml,pdf}' .
to get all xml and pdf files from a remote directory. In general, I prefer this over having convenience with files that have spaces. Files with spaces are always a bother. -
Fractale almost 6 yearswhy it is escape 2 times? any way to change this behavior?
-
Robert Dundon over 5 yearsI didn't have a variable but this satisfied me as a good alternative to 3 backslashes for a path with a lot of spaces. No one has time for that!
-
codeshot almost 5 yearsHow 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?
-
Klajd Deda almost 5 yearsscp [email protected]:"web/tmp/Master\ File\ 18\ 10\ 13.xls" . works
-
uldics about 4 yearsThis is the only one that worked for me on Ubuntu 19.10. No double quotes, no soft and hard quotes in and out, no escaped quotes. Only tripplebackslashed spaces. Very weird. Thank you!
-
opello almost 4 yearsIs there some reason that
${file//\ /\\\ }
is better than${file// /\\ }
? Does that space need escaping for some reason? -
frakman1 almost 4 yearsWhat if the path had a prefix like
/home/user/folder/
followed by the file with spaces? I have to enclose the whole thing with double quotes and escaping the one around the$file
doesn't work. -
Luke Davis almost 4 years@opello Nope, it was not necessary to escape the whitespace. Have fixed the answer.
-
Joshua Pinter almost 4 yearsMind blown. I've never even heard of using triple backslashes. This was the only thing that worked for me on Ubuntu 18. Can someone explain why and when this became necessary? And if it's only for scp or are there other situations you need to use triple backslashes instead of just the one?
-
biomiker over 3 yearsWay underrated. Does not require parsing and modifying the path!!!!
-
Ludovic Kuty over 3 yearsSee answer by @AdrianGunawan. It is escaped once on the local host and then a second time on the remote host. So
\\\_
is escaped once to get\_
and then it is escaped another time to get a space_
. I used_
to clearly represent a space. -
Ludovic Kuty over 3 yearsIf you get a "protocol error: filename does not match request" error, you might want to add option
-T
. See stackoverflow.com/q/54598689/452614 -
Sanchi Girotra over 3 yearsscp [email protected]:web/tmp/Master\\\ File\\\ 18\\\ 10\\\ 13.xls . it worked for me
-
cayhorstmann over 3 yearsIf you are really unlucky and have both backslashes and spaces in your filename, first escape the backslashes and then the spaces:
file=${file//\\/\\\\};file=${file// /\\ }
-
Dave Pile about 3 yearsThank you. I came here looking for a Powershell solution and none of the above worked but this did.
-
Christopher Shroba over 2 yearsI also had to add the -T flag to scp due to a protocol error: stackoverflow.com/q/54598689
-
refex about 2 yearsi effin love you man
-
Slim Aloui about 2 yearsThank you for the printf solution. It's the only one that worked for me. I needed it for both source and destination. FYI, it's possible to put all in same line with ";"
-
Fonic about 2 years@SlimAloui You're welcome. Good suggestion, I added a one-liner for the
printf
alternative. -
Kjell about 2 yearsFor me (on ubuntu) it worked by putting the quotes within the variable:
export file='"foo bar/baz"' ; scp [email protected]:"$file"
. That way I can avoid the substitution. Maybe that is worth including in the answer.