use expect to spawn command with arguments containing spaces
Solution 1
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.
Solution 2
As Johannes said, using '
doesn't work.
I had a similar problem, but I wanted to execute more commands and then still get a login shell. I managed to make it work with "
:
expect -c "
set timeout 5;
spawn ssh -XY $user@$host -t \"cat /etc/motd; bash -l\"
expect {
-re \"^Warning.*\" {exp_continue}
-re \"^.*sword: \" {send \"${PASSWORDS[$user]}\r\"; interact}
}
"
Richard
automate all the things: ask me about bash, ant, awk, and hbase
Updated on August 17, 2020Comments
-
Richard almost 4 years
I want to use
expect
to run a simple commandcat /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
. Myexpect
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, replacingcat /tmp/id_rsa.pub
with other commands with spaces, likeeval spawn ssh root@localhost 'which java'
it complains with
bash: which java: command not found
. But if replacing that withpwd
, likeeval spawn ssh root@localhost 'pwd'
it work fine.