Reputation: 29
It seems like no one is maintaining this repo and this repo any more.
Assuming I'd like to fetch data from remote with user/password
auth automating in expect
script, like the following:
ps: I use sh
to refer ssh/telnet connection
$ expect -v
expect vesion 5.45.4
$ cat expect.sh
#!/usr/bin/expect -f
spawn -noecho sh -c ./download.sh
interact
$ cat download.sh
#!/bin/sh
sh -c 'cat /bin/ls' # cat a binary file
$ ./expect.sh > a.out
$ file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version1 (SYSV), too many program (2304)
As the last command said, captured command ls
(i.e. a.out) has broken locally. And you can find if you actually run the script, the two files are different in bytesize (let alone checksum).
I though it might be related to traslation and encoding issue, so I change the expect.sh
script to this and it still not working
$ cat expect.sh
#!/usr/bin/expect -f
spawn -noecho sh -c ./download.sh
fconfigure $spawn_id -translation binary -encoding binary
fconfigure stdin -translation binary -encoding binary
fconfigure stdout -translation binary -encoding binary
interact
Anybody has any idea?
Upvotes: 0
Views: 589
Reputation: 12255
You should have more success if you set the tty to raw mode first. In expect
this is done by setting global variable stty_init
to the sort of string values you would give the stty
command. For example,
set stty_init raw
log_user 0
spawn ssh user@host "cat /bin/ls; sleep 1"
expect assword: {send mypassword\r}
expect \n
log_user 1
expect eof
Direct the stdout of the above into a file and it should get just the contents of the ls
file. Note how log_user 0
is used to suppress output until we have read past the \n
newline. Also, I had to add a sleep
after the cat otherwise the tty was closed before all the data was read and the file ended up a little shorter than the original. There should probably be a better way of doing that.
Upvotes: 0
Reputation: 20758
Usually dumping a binary file to tty would cause unexpected results. You can just try cat /bin/ls
in an interactive shell and see what would happen. A tty is not a pass-through pipe. It does not output exactly what is sent to it.
See this simple example:
[STEP 101] # printf '\n'
[STEP 102] # printf '\n' | hexdump -C
00000000 0a |.|
00000001
[STEP 103] #
[STEP 104] # expect -c 'spawn -noecho printf \n; expect eof'
[STEP 105] # expect -c 'spawn -noecho printf \n; expect eof' | hexdump -C
00000000 0d 0a |..|
00000002
[STEP 106] #
[STEP 107] # expect -d -c 'spawn -noecho printf \n; expect eof'
expect version 5.45.4
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {57875}
expect: read eof
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "\r\n"
argv[0] = expect argv[1] = -d argv[2] = -c argv[3] = spawn -noecho printf \n; expect eof
set argc 0
set argv0 "expect"
set argv ""
[STEP 108] #
As you can see, \n
is converted to \r\n
when outputted to the tty.
Upvotes: 1