Search code examples
bashshellexpect

Is it possible to suppress the output to terminal before successfully login the telnet?


I can successfully login the Telnet and run ls command by invoking the commands below in bash.

I hope to suppress the output to the terminal before successfully login the telnet?

    expect << EOS
        spawn telnet 192.168.1.11
        expect "login:"
        send "root\r"
        expect "#"
        send "ls\r"
        expect "#"
        send "exit\r"
        expect eof
EOS

Here is the output:

spawn telnet 192.168.1.11
Trying 192.168.1.11...
Connected to 192.168.1.11 .
Escape character is '^]'.

Linux (03:04 on Wednesday,)

Ambarella login: root
Last login: Wed Jun  1 02:57:18 from 192.168.1.11   
# ls  #how to suppress the output above?
test        nw  sample
# exit #how to suppress the output below? 
Connection closed by foreign host.

UPDATED: @wjandrea I carefully read the post. But it seems not what I expect. There is no output for ls either, if I call

expect << EOS
        spawn telnet 192.168.1.11
        log_user 0;
        expect "login:"
        send "root\r"
        expect "#"
        send "ls\r"
        expect "#"
        send "exit\r"
        expect eof
EOS

UPDATED AGAIN: Thanks to @Colin Macleod, @wjandrea and @glenn jackman. There is still a question left. I update the script, but I can't suppress ls. I don't want to see it indeed.

expect << EOS
        log_user 0;
        spawn telnet 192.168.1.11
        expect "login:"
        send "root\r"
        expect "#"
        send "ls\r"
        log_user 1;
        expect "#"
        log_user 0;
        send "exit\r"
        expect eof
EOS

Here is the output:

ls   #how to suppress this line?
test        nw  sample

UPDATE the third time:

Thanks to @glenn jackman.

I try to suppress the echo to pwd which is sent to the remote computer. But it seems that I miss something, it does not work as expected. You see there is no useful message is printed out when puts "the output:$output" is invoked.

Here is the script:

expect << EOS
        log_user 0;
        spawn telnet 192.168.1.11
        expect "login:"
        send "root\r"
        expect "#"
        
        set prompt "#"
        set command "pwd"
        
        log_user 1;
        send "$command\r"
        expect -re "$command\r\n(.+)\r\n$prompt"

        set output $expect_out(1,string)

        puts "the output:$output"

        send "exit\r"
        log_user 0;
        expect eof
EOS

Here is the output, which is seen in the local terminal:

                  //this line is empty
# the output:     //there is a space between `#` and `the output`, and the cursor twinkles for several seconds before `the ouput` is printed out. It seems some command(I guess it's `expect`) is waiting for timeout.

What's more, if I replace send "$command\r" with send "pwd\r". The code snippet works as almost expected.

Here is the code snippet:

expect << EOS
        log_user 0;
        spawn telnet 192.168.1.11
        expect "login:"
        send "root\r"
        expect "#"
        
        set prompt "#"
        set command "pwd"  
        
        log_user 1;
        send "pwd\r"      #modification is at here
        expect -re "$command\r\n(.+)\r\n$prompt"

        set output $expect_out(1,string)

        puts "the output:$output"

        send "exit\r"
        log_user 0;
        expect eof
EOS

Here is the output:

pwd
/root
# the output:   //no valid output, very strange.

And I am using

 expect -version
expect version 5.45.3

Solution

  • This is one of the tricky/aggravating things about expect. What you capture is everything you would see on the screen -- all of the prompt and the command you typed/sent and the command output.

    You need to use the -re option for the expect command to capture the output, and then parse out the command.

    You can do something like this:

    send "ls\r"
    expect -re "(.*)#"
    regexp {ls\r\n(.+)\r\n} $expect_out(1,string) -> ls_output
    

    Note that Expect uses \r\n line endings for the data returned from the spawned process

    Another option, more general:

    set prompt "#"
    
    set command "ls -l"
    send "$command\r"
    expect -re "$command\r\n(.+)\r\n$prompt"
    
    set output $expect_out(1,string)