How do I escape spaces in path for scp copy in Linux?

238,447

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"
Share:
238,447
AlexPandiyan
Author by

AlexPandiyan

Updated on August 02, 2022

Comments

  • AlexPandiyan
    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
    Sacrilicious almost 10 years
    This 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
    Hamy over 9 years
    Here is a relevant question: stackoverflow.com/questions/5608112/…
  • troyfolger
    troyfolger over 6 years
    I would suggest the more robust 'substitute all' expansion: file="${file//\ /\\\ }"
  • Luke Davis
    Luke Davis over 6 years
    Forgot about that distinction -- I'm rusty on my parameter expansions. Thanks!
  • Mauricio Trajano
    Mauricio Trajano over 6 years
    Using single quotes and escaping worked for me but not double quotes
  • Vorsprung
    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
    Michael over 6 years
    This answer is under-rated, considering how many spaces it can handle with the same amount of escape characters. Thanks!
  • Admin
    Admin over 6 years
    ' " path " ' worked while " ' path ' " failed; conclusion single quotes first and then the double quotes to surround
  • jankes
    jankes over 6 years
    Wow! That's probably the single most ridiculous program behaviour I've seen!
  • JoL
    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, or scp [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
    Fractale almost 6 years
    why it is escape 2 times? any way to change this behavior?
  • Robert Dundon
    Robert Dundon over 5 years
    I 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
    codeshot almost 5 years
    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?
  • Klajd Deda
    Klajd Deda almost 5 years
    scp [email protected]:"web/tmp/Master\ File\ 18\ 10\ 13.xls" . works
  • uldics
    uldics about 4 years
    This 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
    opello almost 4 years
    Is there some reason that ${file//\ /\\\ } is better than ${file// /\\ }? Does that space need escaping for some reason?
  • frakman1
    frakman1 almost 4 years
    What 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
    Luke Davis almost 4 years
    @opello Nope, it was not necessary to escape the whitespace. Have fixed the answer.
  • Joshua Pinter
    Joshua Pinter almost 4 years
    Mind 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
    biomiker over 3 years
    Way underrated. Does not require parsing and modifying the path!!!!
  • Ludovic Kuty
    Ludovic Kuty over 3 years
    See 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
    Ludovic Kuty over 3 years
    If 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
    Sanchi Girotra over 3 years
    scp [email protected]:web/tmp/Master\\\ File\\\ 18\\\ 10\\\ 13.xls . it worked for me
  • cayhorstmann
    cayhorstmann over 3 years
    If 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
    Dave Pile about 3 years
    Thank you. I came here looking for a Powershell solution and none of the above worked but this did.
  • Christopher Shroba
    Christopher Shroba over 2 years
    I also had to add the -T flag to scp due to a protocol error: stackoverflow.com/q/54598689
  • refex
    refex about 2 years
    i effin love you man
  • Slim Aloui
    Slim Aloui about 2 years
    Thank 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
    Fonic about 2 years
    @SlimAloui You're welcome. Good suggestion, I added a one-liner for the printf alternative.
  • Kjell
    Kjell about 2 years
    For 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.