4

I have a bash+expect script which has to connect via ssh to the remote comp, read the file there, find specific line with the "hostname" (like "hostname aaaa1111") and store this hostname into the variable to be used after while. How can i get the value of the "hostname" parameter? I thought that line content will be in $expect_out(buffer) variable (so i can scan it and analyze), but it's not. My script is:

    #!/bin/bash        
    ----bash part----
    /usr/bin/expect << ENDOFEXPECT
    spawn bash -c "ssh root@$IP"  
    expect "password:"
    send "xxxx\r"
    expect ":~#"
    send "cat /etc/rc.d/rc.local |grep hostname \n"
    expect ":~#"
    set line $expect_out(buffer)
    puts "line = $line, expect_out(buffer) = $expect_out(buffer)"
    ...more script...
    ENDOFEXPECT

Here http://en.wikipedia.org/wiki/Expect there is an example:

    # Send the prebuilt command, and then wait for another shell prompt.
    send "$my_command\r"
    expect "%"
    # Capture the results of the command into a variable. This can be displayed, or written to disk.
    set results $expect_out(buffer)

seems that it doesn't work in this case, or what's wrong with the script?

lugger1
  • 43
  • 1
  • 1
  • 4
  • [Michael is right](http://serverfault.com/questions/300238/help-with-expect-script-run-cat-on-remote-comp-and-get-output-of-it-to-the-varia/300246#300246). However, the answer to the expect question is: you need `\r` instead of `\n` in your `send` command. – glenn jackman Aug 11 '11 at 20:21
  • I need to use password identification in this script (for some reasons), and expect looks just right for this. And i've tried \r and \n in send command, anyway when i try to see line variable, i see only this: line = , expect_out(buffer) = (buffer) variable is not assigned by any conversion specifiers while executing ... What is the right way to get the line from the file into the variable? – lugger1 Aug 12 '11 at 16:09
  • Or it might be a way to open and read and scan the file on the remote comp using expect itself, without "send"? – lugger1 Aug 12 '11 at 16:45
  • No, because expect is running on your local machine, so you have to "send" the commands to the ssh process. – glenn jackman Aug 12 '11 at 17:52

2 Answers2

3

Why are you using expect for this?

ssh -i ssh_private_key root@${IP} "grep -E -o 'hostname.*$' /etc/rc.d/rc.local"
Michael Lowman
  • 3,584
  • 19
  • 36
3

First thing, your heredoc acts like a double quoted string, so the $expect_out variable is being substituted by the shell before expect starts. You need to ensure your heredoc is not being touched by the shell. Therefore, any shell variables need to be fetched in a different way. Here, I'm assuming IP is a shell variable, and I'm passing it through the environment.

export IP
/usr/bin/expect << 'ENDOFEXPECT'
  set prompt ":~#"
  spawn ssh root@$env(IP)  
  expect "password:"
  send "xxxx\r"
  expect $prompt
  send "grep hostname /etc/rc.d/rc.local \n"
  expect $prompt
  set line $expect_out(buffer)
  ...more script...
ENDOFEXPECT
glenn jackman
  • 4,320
  • 16
  • 19
  • Thanks glenn. IP is a variable defined in the "bash part", it's an argument to the script actually. I re-wrote this part, but still output is: `expect_out = (buffer) grep hostname /etc/rc.d/rc.local hostname aaa1111 :~# line = , expect_out(buffer) = (buffer)` etc – lugger1 Aug 12 '11 at 18:14
  • Ok, even if i change it so that all expect part is now a separate script (called by the bash script), still i can't get what i want. The script goes like this: `send "grep hostname /etc/rc.d/rc.local \r" expect $prt set line $expect_out(buffer) puts "line = $line, expect_out(buffer)=$expect_out(buffer), expect_out(0,string)=$expect_out(0,string)"`, and the output (sirprisingly to me) is now: `expect_out(buffer)= grep hostname /etc/rc.d/rc.local` – lugger1 Aug 12 '11 at 18:27