Prevent expansion of `~`

376 views Asked by At

I have a script which sync's a few files with a remote host. The commands that I want to issue are of the form

rsync -avz ~/.alias user@y:~/.alias

My script looks like this:

files=(~/.alias ~/.vimrc)

for file in "${files[@]}"; do
    rsync -avz "${file}" "user@server:${file}"
done

But the ~ always gets expanded and in fact I invoke the command

rsync -avz /home/user/.alias user@server:/home/user/.alias

instead of the one above. But the path to the home directory is not necessarily the same locally as it is on the server. I can use e.g. sed to replace this part, but it get's extremely tedious to do this for several servers with all different paths. Is there a way to use ~ without it getting expanded during the runtime of the script, but still rsync understands that the home directory is meant by ~?

2

There are 2 answers

0
tripleee On BEST ANSWER
files=(~/.alias ~/.vimrc)

The paths are already expanded at this point. If you don't want that, escape them or quote them.

files=('~/.alias' \~/.vimrc)

Of course, then you can't use them, because you prevented the shell from expanding '~':

~/.alias: No such file or directory

You can expand the tilde later in the command using eval (always try to avoid eval though!) or a simple substitution:

for file in "${files[@]}"; do
    rsync -avz "${file/#\~/$HOME/}" "user@server:${file}"
done
3
anubhava On

You don't need to loop, you can just do:

rsync -avz ~/.alias/* 'user@y:~/.alias/'

EDIT: You can do:

files=(.alias .vimrc)

for file in "${files[@]}"; do
    rsync -avz ~/"${file}" 'user@server:~/'"${file}"
done