How do I escape spaces in path for scp copy in 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 ael5105@192.168.0.200:'/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.
Double check that the file really exists. Put the quotes around the whole path, including the login name and ip address. Alternatively, remote the quotes and prepend the space with a backslash instead.
13 Answers 13
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 user@example.com:"web/tmp/Master\ File\ 18\ 10\ 13.xls" . scp user@example.com:web/tmp/Master\\\ File\\\ 18\\\ 10\\\ 13.xls .
Another option only works with older versions of OpenSSH and possibly other clients:
scp user@example.com:"'web/tmp/Master File 18 0 13.xls'" .
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.
‘ » path » ‘ worked while » ‘ path ‘ » failed; conclusion single quotes first and then the double quotes to surround
@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 user@example.com:’$(ls -t | head -1)’ . to get the most recently created file in the server, or scp user@example.com:’dir/*.
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?
scp localhost:"f/a\ b\ c" . 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.
@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
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 .
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!
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?
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.
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.
This answer is under-rated, considering how many spaces it can handle with the same amount of escape characters. Thanks!
I encountered similar issues when trying to copy files from remote paths containing spaces using scp from within a Bash script.
Here are the solutions I came up with:
Escape paths manually:
scp user@host:'dir\ with\ spaces/file\ with\ spaces' scp user@host:"dir\\ with\\ spaces/file\\ with\\ spaces" scp user@host:dir\\\ with\\\ spaces/file\\\ with\\\ spaces
Note: does not require option -T (see below).
Use double-quoting + option -T :
scp -T user@host:"'path with spaces'" scp -T user@host:'"path with spaces"' scp -T user@host:"\"path with spaces\""
Note: without option -T , these commands fail with protocol error: filename does not match request . The reason for this is discussed in detail here.
Escape path using Bash’s printf:
source="path with spaces" printf -v source "%q" "$" scp user@host:"$"
source="path with spaces"; printf -v source "%q" "$"; scp user@host:"$"
Note: works fine without option -T .
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 «;»
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 user@example.com:"'$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=$ scp user@example.com:"$file"
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!
Sorry for using this Linux question to put this tip for Powershell on Windows 10: the space char escaping with backslashes or surrounding with quotes didn’t work for me in this case. Not efficient, but I solved it using the «?» char instead:
for the file «tasks.txt Jun-22.bkp» I downloaded it using «tasks.txt?Jun-22.bkp»
scp ael5105@192.168.0.200:/home/5105/test/gg/Untitled?Folder/a/qy.jpg /var/www/try/
the ? does a glob on the remote and will match any character, including a space
I’m new to Linux and I used Kali xD, here how’s mine works: From your system to remote server if you want to transfer your file with single or multiple spaces:
$ scp this\ is\ my\ file tryhackme@1.1.1.1:/home/tryhackme
Note that the IP address is only example and the last I type is directory and the dollar sign which is the prompt, the code start with scp.
Also you can specifiy what name you want to that file when it is transfer, ex. /home/tryhackme/file1 or with single or multiple spaces like /home/tryhackme/»this\ is\ new\ file» .
From remote server to your system, same as above with single or multiple spaces:
$ scp tryhackme@1.1.1.1:/home/tryhackme/"remote\ server\ file" "this is mine now"
Note that you only use backward slash \\ to the file you want to copy, as you can see that the string «this is mine now» has no \\ because that is the name of the file we want when it transfer to our system and not the file that we want to secure copy (scp). Sorry for my explanation, I hope someone will understand, I hope this helps to someone who needs another solution.
How to Tackle Filenames With Spaces in Linux
Spaces in the file names could be tricky, specially for new Linux users. Learn how to deal with them.
The one thing you’ll notice that files in Linux usually do not contain names. Your teacher or colleague use underscore instead of spaces in file and directory names.
It’s not that you cannot use spaces in file names in Linux terminal. It’s just that it creates additional pain and that’s why you should avoid it wherever possible.
Why? Let me show that with examples. You know the generic syntax for Linux commands:
command [options] argument1 argument2
In here, the arguments are separated by spaces. If you try to use filenames with spaces directly, it will be treated as separate arguments rather than just one argument.
In the above screenshot, when I try to use cat agatha books command, it doesn’t understand that agatha books is a single argument. It treats agatha and books as different filenames.
How do you deal with spaces in filename, then? There are two ways:
Wrap the entire filename between quotes:
Escape every space using backslash key:
Tab completion often works with spaces as well. Your terminal may show the file name with space escaped with backslash if you press tab key for the filename.
Read a file with spaces in filename
To use a filename with spaces in it, you can wrap it in quotes like this:
cat "file name with spaces"
You may also escape every space with backslash but it is more work and more confusing than the previous method:
cat file\ name\ with\ spaces
Basically, you put a \ before every space in the filename.
You could also use single quotes instead of double quotes.
cat 'file name with spaces'
Single quotes ignore any special characters. Double quotes ignores all except $, back quotes and baclslashes. More on it in some other tutorial.
Create a file with space in filename
Now, you need to type space in terminal to create the filename here. Use backslash or quotes again.
Similar to the previous section, you can create new files with spaces in the filename using quotes:
touch "file name with spaces"
touch file\ name\ with\ spaces
Dealing with space in folder name
You can create a directory with space in its name the same way you create a file.
Now, if you want to switch to this directory, you’ll have a path with spaces.
But that should not be a problem for you anymore. To cd into a directory with space, use quotes or backslash again.
Basically, whenever you have to deal with spaces in names, you use quotes or backslash keys.
Suppose you have to copy a file my file from this new dir . Here’s what you can do:
Now it starts to get confusing a bit, right? There are backslashes and forward slashes. It could intimidate a new user or even a seasoned one if there are way too many of those slashes.
It gets even messier when there are backslashes in the filename. Then you’ll be seeing double backsplashes.
This is the reason why you should try and avoid using spaces or other special characters in file names. To separate the words in a file name, use underscore.
touch a_very_long_file_name_with_too_many_words
This makes the filenames easier to read and you won’t have to make the extra effort to deal with those spaces in the filenames.
How to access files/directories with spaces in the name? [duplicate]
Through terminal I can’t access files or directories with a spaces in their names. The cd command says no such file or directory . Is there any way to do it or should I rename all files with spaces?
2 Answers 2
To access a directory having space in between the name use \ to access it. You can also use Tab button to auto completion of name.
guru@guru-Aspire-5738:~$ cd /media/Data/My\ Data/ guru@guru-Aspire-5738:/media/Data/My Data$.
To to use files with spaces you can either use the escape character or youse the double quotes.
\ is called escape character, used to not expansion of space, so now bash read the space as part of file name.
Now to rename files, it’s so easy to rename all files with spaces and replace space with underscore:
for file in * ; do mv "$f" "$" ; done
look at answer here there is a script to rename all files and dirs recursively.
The script is:(All rights go to its owner)
#!/bin/bash # set -o xtrace # uncomment for debugging declare weirdchars=" &\'" function normalise_and_rename() < declare -a list=("$") for fileordir in "$"; do newname="$]/_>" [[ ! -a "$newname" ]] && \ mv "$fileordir" "$newname" || \ echo "Skipping existing file, $newname." done > declare -a dirs files while IFS= read -r -d '' dir; do dirs+=("$dir") done < <(find -type d -print0 | sort -z) normalise_and_rename dirs[@] while IFS= read -r -d '' file; do files+=("$file") done < <(find -type f -print0 | sort -z) normalise_and_rename files[@]