Etan Etan - 2 months ago 22
Linux Question

Expect script for rsync with quotation marks

I want to rsync a folder to another machine. sshpass is not an option and certificates don't either. So I'm stuck with expect.

So far, I have this bash script (minimized).

read -p "Enter remote IP: " IP
read -p "Enter remote user: " USER
read -s -p "Enter remote password: " PASSWORD
expect <<EOF
set timeout -1
spawn rsync -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
-aHv --exclude=".*/" --delete ../.. ${USER}@${IP}:~/destination
expect "password: "
send "${PASSWORD}\n"
expect eof
EOF


Problem is that rsync doesn't respect the "--exclude" option.
In the stdout, I see:

spawn rsync -e ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -aHv --exclude=".*/" --delete ../.. pi@10.0.1.2:~/OberonHAP


Somehow, the quotes around the -e option vanished, but exclude still has them.

So I escape the quotes

expect <<EOF
set timeout -1
spawn rsync -e \"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" \
-aHv --exclude=".*/" --delete ../.. ${USER}@${IP}:~/destination
expect "password: "
send "${PASSWORD}\n"
expect eof
EOF


but now I get

Missing trailing-" in remote-shell command.


Note that the command itself works perfectly when typed directly into a Terminal.

I've also tried different things, like 'EOF' heredoc and passing in the variables via environment, but always get error messages of different sorts :-)

How do I have to escape the rsync command so that it works fine?

Answer

Tcl's syntax (and hence Expect's syntax) is not the same as that of the shell. In particular, the quoting rules are different; you don't need to put double-quoting in the middle of a word as Tcl doesn't expand glob characters for you (you'd need to call glob explicitly if you wanted that). This means that your spawn command is actually best written as:

spawn rsync -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
    -aHv --exclude=.*/ --delete ../.. ${USER}@${IP}:~/destination
#                ☝☝☝☝☝☝ LOOK HERE!