I want to use expect
to run a simple command cat /tmp/id_rsa.pub
over ssh.
In a shell, I can run this wo problem, (with manually put in the password)
ssh root@localhost 'cat /tmp/id_rsa.pub'
I want to automate this with expect
. My expect
script is,
#!/usr/bin/expect
eval spawn ssh root@localhost 'cat /tmp/id_rsa.pub'
expect "password:"
send "123456"
expect eof
It throws error bash: cat /tmp/id_rsa.pub: no such file or directory
. it looks very strange to me. What could be the possible cause?
Edit: after some testing, I find this is common, not only in the case of cat
. If the argument to spawned command is with space (even if it's in the quotes), it will have problem. For example, replacing cat /tmp/id_rsa.pub
with other commands with spaces, like
eval spawn ssh root@localhost 'which java'
it complains with bash: which java: command not found
. But if replacing that with pwd
, like
eval spawn ssh root@localhost 'pwd'
it work fine.
Single quotes ('
) have no special meaning to Expect, unlike sh and other compatible shells.
This means that your statment
spawn ssh root@localhost 'cat /tmp/id_rsa.pub'
is parsed into the following words:
spawn
ssh
root@localhost
'cat
- not until the other single quote./tmp/id_rsa.pub'
The usage in sh is to group this to a single argument. In Tcl you could either use double quotes ("
) or curly brackets ({}
). Inside double quotes, Tcl variables will be substituted, while the content inside {}
is passed without any substitution1.
tl;dr The Expect/Tcl equivalent of sh's '
are {}
.
1 A \
before a newline will still be substitued.