From: howardbryden on 27 Sep 2006 03:56 I'm attempting to pipe commands to ssh(1) while also using Expect to handle the optional dialog that ssh can generate. I'm using version 5.43.0 under HP-UX 11.11. My Expect script is as follows: ########## if [catch "spawn -noecho /usr/bin/ssh -i ~/.ssh/id_rsa_SVC -l admin dessvc" reason] { send_error -- "x: Failed to spawn SSH: $reason\n" exit 1 } set timeout -1 log_user 0 expect { -exact "Are you sure you want to continue connecting (yes/no)? " { send -- "yes\r"; exp_continue } -exact "yes\r\n" exp_continue -re "Warning: Permanently added '.*' (.*) to the list of known hosts.\r\r\n" exp_continue -exact "Enter passphrase for key '/root/.ssh/id_rsa_SVC': " { send -- "passphrase\r" } -re "Enter passphrase for RSA key '.*': " { send -- "passphrase.\r" } -re "..*" { send_error -- "$expect_out(0,string)" } } expect -re "^\r\n" close_on_eof 0 interact expect exit ########## The command line invocation is echo "{command1} {command2} exit" | expect -f {script} where {command1} and {command2} are arbitrary commands and {script} is of course the above Expect script. Using the close_on_eof / interact / expect sequence as per the thread http://groups.google.com/group/comp.lang.tcl/browse_frm/thread/b75184d13782f114/f731162c65184d7a?lnk=gst&q=expect+pipe+input+interact&rnum=1#f731162c65184d7a ("using Expect as path in pipe"), above pipe hangs. Using Expect's -d option to trigger debugging, the final part of the trace was (I've explicitly inserted linefeeds after the \r\n sequences to hopefully render it a bit clearer): expect: does "\r\n" (spawn_id exp6) match regular expression "^\r\n"? yes expect: set expect_out(0,string) "\r\n" expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) "\r\n" spawn id exp0 sent <svcinfo lsnode\nsvcinfo lsnode\nexit\n> interact: received eof from spawn_id exp0 expect: read eof expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) "{command1}\r\n {command2}\r\n exit\r\n Last login: Wed Sep 27 17:20:34 2006 from 10.2.82.100\r\r\n {command1}\r\n {command2}\r\n exit\r\n IBM_2145:DES_SVC1:admin>{command1}\r\n {output from command1}\r\n IBM_2145:DES_SVC1:admin>{command2}\r\n {output from command2}\r\n IBM_2145:DES_SVC1:admin>exit\r\n exit\r\n Connection to dessvc closed.\r\r\n" write() failed to write anything - will sleep(1) and retry... Seeing that the output was apparently being received into expect_out(buffer), I then thought that send_user could dump the output, so I recast the final part of the Expect script thusly: .... close_on_eof 0 interact expect send_user -- "$expect_out(buffer)" exit But, no dice, the final part of the debug trace was: send: spawn id exp0 not open while executing "send_user -- "$expect_out(buffer)"" (file "z" line 24) write() failed to write anything - will sleep(1) and retry... send_tty worked though: .... close_on_eof 0 interact expect send_tty -- "$expect_out(buffer)" exit The output now appeared as: svcinfo lsnode svcinfo lsnode exit Last login: Wed Sep 27 17:34:18 2006 from 10.2.82.100 svcinfo lsnode svcinfo lsnode exit IBM_2145:DES_SVC1:admin>{command1} {output from command1} IBM_2145:DES_SVC1:admin>{command2} {output from command2} exit Connection to dessvc closed. However: 1. send_tty of course sends its output to the session terminal, not to stdout as such. I'd like to know why send_user didn't do that. 2. Even the output as produced by send_tty included extraneous stuff like the input commands and prompt strings. Ideally I would have like just the outputs, in this case the {output from command1} and {output from command2} sections. Is this possible? 3. The close_on_eof setting was not advertised in the Expect manpage. Indeed it announces a date of 29 December 1994, perhaps it needs an update. Thanks for any help.
From: Bezoar on 27 Sep 2006 14:50 howardbryden(a)compuserve.com wrote: > I'm attempting to pipe commands to ssh(1) while also using Expect to > handle the optional dialog that ssh can generate. I'm using version > 5.43.0 under HP-UX 11.11. > > My Expect script is as follows: > > ########## > if [catch "spawn -noecho /usr/bin/ssh -i ~/.ssh/id_rsa_SVC -l admin > dessvc" reason] { > send_error -- "x: Failed to spawn SSH: $reason\n" > exit 1 > } > > set timeout -1 > log_user 0 > > expect { > -exact "Are you sure you want to continue connecting (yes/no)? " { > send -- "yes\r"; exp_continue } > -exact "yes\r\n" exp_continue > -re "Warning: Permanently added '.*' (.*) to the list of known > hosts.\r\r\n" exp_continue > -exact "Enter passphrase for key '/root/.ssh/id_rsa_SVC': " { send > -- "passphrase\r" } > -re "Enter passphrase for RSA key '.*': " { send -- "passphrase.\r" > } > -re "..*" { send_error -- "$expect_out(0,string)" } > } > > expect -re "^\r\n" > > close_on_eof 0 > interact > expect > exit > ########## > > The command line invocation is > > echo "{command1} > {command2} > exit" | expect -f {script} > > where {command1} and {command2} are arbitrary commands and {script} is > of course the above Expect script. > > Using the close_on_eof / interact / expect sequence as per the thread > http://groups.google.com/group/comp.lang.tcl/browse_frm/thread/b75184d13782f114/f731162c65184d7a?lnk=gst&q=expect+pipe+input+interact&rnum=1#f731162c65184d7a > ("using Expect as path in pipe"), above pipe hangs. > > Using Expect's -d option to trigger debugging, the final part of the > trace was (I've explicitly inserted linefeeds after the \r\n sequences > to hopefully render it a bit clearer): > > expect: does "\r\n" (spawn_id exp6) match regular expression "^\r\n"? > yes > expect: set expect_out(0,string) "\r\n" > expect: set expect_out(spawn_id) "exp6" > expect: set expect_out(buffer) "\r\n" > spawn id exp0 sent <svcinfo lsnode\nsvcinfo lsnode\nexit\n> > interact: received eof from spawn_id exp0 > expect: read eof > expect: set expect_out(spawn_id) "exp6" > expect: set expect_out(buffer) "{command1}\r\n > {command2}\r\n > exit\r\n > Last login: Wed Sep 27 17:20:34 2006 from 10.2.82.100\r\r\n > {command1}\r\n > {command2}\r\n > exit\r\n > IBM_2145:DES_SVC1:admin>{command1}\r\n > {output from command1}\r\n > IBM_2145:DES_SVC1:admin>{command2}\r\n > {output from command2}\r\n > IBM_2145:DES_SVC1:admin>exit\r\n > exit\r\n > Connection to dessvc closed.\r\r\n" > write() failed to write anything - will sleep(1) and retry... > > > Seeing that the output was apparently being received into > expect_out(buffer), I then thought that send_user could dump the > output, so I recast the final part of the Expect script thusly: > > ... > close_on_eof 0 > interact > expect > send_user -- "$expect_out(buffer)" > exit > > > But, no dice, the final part of the debug trace was: > > send: spawn id exp0 not open > while executing > "send_user -- "$expect_out(buffer)"" > (file "z" line 24) > write() failed to write anything - will sleep(1) and retry... > > > send_tty worked though: > > ... > close_on_eof 0 > interact > expect > send_tty -- "$expect_out(buffer)" > exit > > > The output now appeared as: > > svcinfo lsnode > svcinfo lsnode > exit > Last login: Wed Sep 27 17:34:18 2006 from 10.2.82.100 > svcinfo lsnode > svcinfo lsnode > exit > IBM_2145:DES_SVC1:admin>{command1} > {output from command1} > IBM_2145:DES_SVC1:admin>{command2} > {output from command2} > exit > Connection to dessvc closed. > > > However: > > 1. send_tty of course sends its output to the session terminal, not to > stdout as such. I'd like to know why send_user didn't do that. > > 2. Even the output as produced by send_tty included extraneous stuff > like the input commands and prompt strings. Ideally I would have like > just the outputs, in this case the {output from command1} and {output > from command2} sections. Is this possible? > > 3. The close_on_eof setting was not advertised in the Expect manpage. > Indeed it announces a date of 29 December 1994, perhaps it needs an > update. > > > Thanks for any help. try piping your commands to a shell executed by ssh like so put in your own values for user, host, password, I changed the expect part to test but you can modify the actual ssh options and expect text string to your requirements. #!/opt/usr/bin/tclsh8.4 package require Expect # read in input set buff [read stdin ] if [catch {spawn /usr/bin/ssh -i ~/.ssh/id_dsa.pub $user@$host "/bin/sh" } reason] { send_user -- "x: Failed to spawn SSH: $reason\n" exit 1 } set timeout -1 log_user 0 expect { -re ".*password:" { exp_send "$password\r" exp_continue; } -re ".* (yes/no)? " { send -- "yes\r"; { exp_continue } -re ".*Warning: Permanently .*known hosts.\r\r\n" exp_continue } -re "..*" { send_error -- "$expect_out(0,string)" } } exp_send "$buff\r" expect { eof { puts "$expect_out(buffer)" } } catch { exp_close -i $spawn_id } # comment this out to just get output from your command puts " [ exp_wait -i $spawn_id -nowait ]" suppose above is in fiel expectpipe.tcl then echo "ls -la /tmp; exit " | expectpipe.tcl would give you : drwxrwxrwt 34 root root 69632 Sep 27 12:23 . drwxr-xr-x 30 root root 4096 Sep 13 10:42 .. ... 12989 exp4 0 0
From: howardbryden on 29 Sep 2006 00:06 Bezoar wrote: > I changed the expect part to test but you can modify the actual ssh options and expect text string to your requirements. > ... > exp_send "$buff\r" > expect { > eof { > puts "$expect_out(buffer)" > } > } .... Unfortunately the target host (an IBM SVC) apparently offered only a restricted shell and so I could not run /bin/sh. I found that exp_send hung but if I recast this section to expect { -re "{promptstring}" { send "$buff\r" } } expect { eof { puts "$expect_out(buffer)" } } (where {promptstring} is the prompt issued by the program), then I get the output. There's still the problem of separating the output from echoed command strings and other stuff, but that's a more manageable problem. Thanks.
|
Pages: 1 Prev: Embedding Tk in an MFC application Next: Problems building Tcl and Expect in MinGW |