Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I scp a file with a colon in the file name?

Tags:

bash

scp

escaping

I'm trying to copy a file using scp in bash with a colon (:) character in the source filename. The obfuscated version of my command I'm using is:

scp file\:\ name.mp4 user@host:"/path/to/dest" 

I get this error:

ssh: Could not resolve hostname Portal 2: Name or service not known 

I know I could just rename the file and remove the :, but I'd like to know if it's possible to escape the colon.

like image 938
Nathan Jones Avatar asked Feb 05 '13 23:02

Nathan Jones


People also ask

Can a file name have a colon?

On Windows systems, files and directory names cannot be created with a colon (:).

How do you put a colon in a filename?

The character code for the colon-like symbol is 02F8. The reason for the Subscript setting is to position the symbol lower relative to its vertical position. The bold and larger font settings are applied so that the symbol is more discernible on the page, and have no affect when used in a file or folder name.

How do you scp a directory with spaces in the filename?

3. Escape Spaces with Both Backslash and Quotation in Scp. The third method of escaping spaces in path names is by combining backslash and quotation marks. This is especially important when copying files from a remote computer.

How do I scp an entire file?

To copy a directory (and all the files it contains), use scp with the -r option. This tells scp to recursively copy the source directory and its contents. You'll be prompted for your password on the source system ( deathstar.com ). The command won't work unless you enter the correct password.


2 Answers

Not quite a bash escaping problem, it's scp treating x: as a [user@]host prefix, try:

scp ./file:\ name.mp4 user@host:"/path/to/dest" 

Using relative (e.g. ./) or fully qualified paths (/path/to/source) prevents this behaviour - the presence of / before a : causes OpenSSH to stop checking for a possible host: or user@host: prefix).

OpenSSH's scp only special-cases filenames that start with a colon allowing those to work without problems, it has no support for escaping a : in the normal sense, and has no other notion of valid hostnames so almost any filename with a : can cause this (or equivalent IPv6 behaviour if [ ] are found before :).

This can also affect other programs, e.g. rsync, the same workaround applies there.

(Due to OpenSSH's simplistic parsing of [] enclosed IPv6 addresses, you can successfully scp files containing : which start with [, or contain @[ before the : and do not contain ]: , but that's not generally useful ;-)


(The below text was written when the original question was How do I escape a colon in bash? It applies to that situation, but not to scp as no amount of shell escaping will help there.)

To answer the question about how to escape :, you don't need to, but "\:" works. Places that a : is used:

  1. the null command :, no need to escape, though you can, just like \e\c\h\o foo it has no effect on the command ("no effect" is not completely true, if you escape one or more characters it will prevent an alias being matched, and you can alias :)
  2. PATH (and others, CDPATH, MAILPATH) escaping the values has no useful effect (I have been unable to run a program in my PATH from a directory containing a :, which is a little unexpected)
  3. parameter expansion ${name:-x} and more, name must be [a-zA-Z_][a-zA-Z0-9_], so no need to escape variables names, and since there's no ambiguity, no need to escape subsequent : in the other variations of parameter expansion
  4. ? : trinary operates only on variables and numbers, no need to escape
  5. == and =~ with classes in the pattern like [[:digit:]], you can escape with \: but I'm at a loss as to how that might ever be useful...
  6. within command or function names, no need to escape, \: has no useful effect

(Note that the null command is just :, you can have a command or function named like ":foo" and it can be invoked without escaping, in this respect it's different to # where a command named #foo would need to be escaped.)

like image 167
mr.spuratic Avatar answered Oct 21 '22 00:10

mr.spuratic


I try using fully qualified paths as @mr.spuratic answer but not work and in my situation, I have to use absolute paths, this is my solution:

scp `hostname`:/root/this/is/test/file.txt user@host:"/path/to/dest" 
like image 20
yelliver Avatar answered Oct 20 '22 22:10

yelliver