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

Nathan Jones picture Nathan Jones · Feb 6, 2013 · Viewed 18.3k times · Source

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.

Answer

mr.spuratic picture mr.spuratic · Feb 6, 2013

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.)