Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

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

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...