rsyncをexpectで動かしたかった
4月11日のエントリで書いた件。これをexpectをつかって自動化しようとしました。
書いたスクリプトがこんなの。
#!/usr/bin/expect set timeout -1 spawn sudo rsync -auvz -e "sudo -u hoge ssh -l hoge" --rsync-path="sudo rsync" /usr/local/apache2/ server1:/usr/local/apache2/ expect { -re "Enter passphrase for key .*: " { send "password\n" } }
ところがこれがちゃんと動作しない。spawnでrsyncは起動しているし、expectで"Enter passphrase for.."もちゃんとキャッチしている。ところが、sendしてくれないでスルッと終了する。
なぜだと悩むこと3時間ほど。expectのmanを繰り返し読んでいるとこんな記述を見つけました。
send [-flags] string Sends string to the current process. For example, the command send "hello world\r" sends the characters, h e l l o <blank> w o r l d <return> to the current process. (Tcl includes a printf-like command (called format) which can build arbitrarily complex strings.)
sendのところの説明ですね。カレントプロセスに文字列を送付するとあります。
上記に例で"Enter passphrase for key.."と聞いているのはexpectのspawnで起動されたrsyncではなく、rsync中の-eオプションで指定されているssh。つまりexpectからみてカレントプロセスではないんですな。
仕方がないので、ノーパスワードの鍵ペアを作ってsshを張ることにします。