问题
I want to automate rsyncing, and tried the following code:
TARGET="/media/USB\ DISK/Backup/"
rsync -av --delete ~/Data ${TARGET}
but the execution results in the following error:
rsync: link_stat "/media/USB\" failed: No such file or directory (2)
rsync: mkdir "/home/DISK/BACKUP" failed: No such file or directory (2)
because of the 'space' in the target filename. However, when I echo
the command I can use that to run on the shell directly.
How to do it correctly (which brackets, with backslash or without?) and why?
回答1:
There are two possibilities:
TARGET="/media/USB DISK/Backup/"
rsync -av --delete ~/Data "${TARGET}"
or
TARGET=/media/USB\ DISK/Backup/
rsync -av --delete ~/Data "${TARGET}"
The first one preserves the space by quoting the whole string. The second one preserves the space by escaping it with a backslash. Also, the argument to the rsync
command needs to be quoted.
When the string is both double-quoted and the space is preceded by a backslash, as in TARGET="a\ b"
, the result is that TARGET
contains a literal backslash which is probably not what you wanted. For more details, see the section entitled "Quoting" in man bash
.
回答2:
You should use quotes around your string. String should be quoted both at declaration and when used/called.
Why use quotes ?
Metacharacters [1]
The first function of quoting is to permit words to contain these metacharacters.
Word splitting and globbing [2]
The second purpose of quoting is to prevent word splitting and globbing.
Type of quotes
For details read the Types of quoting section.
Simple quotes (POSIX)
Everything between single quotes is literal and expands to a single word
Double quotes (POSIX)
permit the shell to parse their contents for those types of expansions that are prefixed with a
$
sign - parameter expansions, arithmetic expansions and command substitutions, while treating all other content as literal […]
Bash quoting $'…'
and $"…"
Those are non-POSIX (supported by Bash, Ksh93, etc.):
$'…'
: allow backslash-escaped sequence to be used/expanded (\n
,\t
, etc.) ;$"…"
: for translation
References
- http://mywiki.wooledge.org/Quotes ;
- http://wiki.bash-hackers.org/syntax/quoting.
回答3:
Try this. I think the curly braces (parameter expansion) messed it up.
TARGET="/media/USB DISK/Backup/"
rsync -av --delete ~/Data "$TARGET"
来源:https://stackoverflow.com/questions/20480070/how-to-handle-space-in-filename-in-bash-script