Hide output from expect
Try adding
log_user 0
to your script. That should turn off the display to stdout.
If you want to turn it on again for the "do some thing" part of the program, re-enable it
log_user 1
Suppress expect output
You see the extra line because you gave the command log_user 1
before send "show..."
, which causes the echo of "show..."
to be logged to the stdout. If you move this command one line later, after the send
, and also wait for the echo to complete by adding an expect "\n"
, then you will see less:
expect "#"
send "show bgp vrf IKA summary | include 10.155.192.50\n"
expect "\n"
log_user 1
expect "#"
Note, the *
glob character at the start of a pattern serves no purpose.
Alternatively, instead of changing log_user
you should look at using variable $expect_out(buffer)
which holds what matched up to the pattern, inclusive.
Suppress expect output
You see the extra line because you gave the command log_user 1
before send "show..."
, which causes the echo of "show..."
to be logged to the stdout. If you move this command one line later, after the send
, and also wait for the echo to complete by adding an expect "\n"
, then you will see less:
expect "#"
send "show bgp vrf IKA summary | include 10.155.192.50\n"
expect "\n"
log_user 1
expect "#"
Note, the *
glob character at the start of a pattern serves no purpose.
Alternatively, instead of changing log_user
you should look at using variable $expect_out(buffer)
which holds what matched up to the pattern, inclusive.
How to suppress expect send output?
Many programs echo their input. For example, if you send the date
command to the shell, you will see the string date followed by a date. More precisely, you will see everything that you would ordinarily see at a terminal. This includes formatting, too.
send "date\r"
expect -re $prompt
The command above ends with expect_out (buffer)
set to date\r\nFri Nov 7 20:47:32 IST 2014\r\n
. More importantly, the string date has been echoed. Also, each line ends with a \r\n
, including the one you sent with a \r
. The echoing of date has nothing to do with the send
command.
To put this another way, there is no way to send the string and have send not echo it because send is not echoing it in the first place. The spawned process is.
In many cases, the spawned process actually delegates the task of echoing to the terminal driver, but the result is the same-you see your input to the process as output from the process.
Often, echoed input can be handled by using log_user
only (which you have used in different place). As an example, suppose a connection to a remote host has been spawned and you want to get the remote date, but without seeing the date command itself echoed. A common error is to write:
log_user 0 ;# WRONG
send "date\r" ;# WRONG
log_user 1 ;# WRONG
expect -re .*\n ;# WRONG
When run, the log_user
command has no effect because expect
does not read the echoed "date" until the expect
command. The correct way to solve this problem is as follows:
send "date\r"
log_user 0
expect -re "\n(\[^\r]*)\r" ;# match actual date
log_user 1
puts "$expect_out(l,string)" ;# print actual date only
If you are sending a lot of commands to a remote shell it may be more convenient to just disable all echoing in the first place. You can spawn a shell and then send the command stty -echo
, after which your commands will no longer be echoed. stty echo
re enables echoing.
spawn ssh <host>
stty -echo; # Disable 'echo' here
expect something
#Your further code here
stty echo # Enable 'echo' here
#Close of connection
Reference : Exploring Expect
hide perl Expect output
The docs tell you to use
$exp->log_stdout(0);
Tested:
$ perl -MExpect -E'
my $e = Expect->spawn("cat");
$e->log_stdout($ARGV[0]);
$e->send("abc\n"); $e->expect(undef, "abc");
$e->send("def\n"); $e->expect(undef, "def");
say "done."
' 1
abc
def
done.
$ perl -MExpect -E'
my $e = Expect->spawn("cat");
$e->log_stdout($ARGV[0]);
$e->send("abc\n"); $e->expect(undef, "abc");
$e->send("def\n"); $e->expect(undef, "def");
say "done."
' 0
done.
Is it possible to suppress the output to terminal before successfully login the telnet?
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)
expect output only stdout of the command and nothing else
Capturing the output from sent commands is a bit of a pain in expect.
Here's a more general case that does not rely on the log_user setting, it captures the output with a regular expression:
#!/usr/bin/expect
log_user 0
spawn bash
# set the prompt to a known value
send "PS1='>'\r"
expect -re {>$}
# send a command: we don't know what the output is going to be
send "echo \$RANDOM\r"
# capture the portion of the output that occurs just before the prompt
expect -re "\r\n(.*?)\r\n>$"
puts "output is: $expect_out(1,string)"
send "exit\r"
expect eof
A thought just occurred to me: if the command does not require any interaction, then expect is overkill: just use exec
set output [exec bash -c {echo $RANDOM}]
How to turn off stderr in Expect script or stop Connection to ... closed message after exiting?
It is just the incorrect use of log_user
. It should be used as,
log_user 0
send "logout\r"
expect eof
log_user 1
Note that I am expecting for eof
pattern after sending logout\r
, because it will lead to the closure of the connection. Always use \r
in place of \n
while using the send
command.
Read here to know more about the log_user
to suppress the output.
Instead of having a prompt to defined as a static string, it can be generalized as,
# We escaped the `$` symbol with backslash to match literal '$'
# The last dollar sign represents line-end.
set prompt "#|>|%|\\\$ $";
While the expect is used, we have to accompany with -re flag to specify that as a regular expression.
expect -re $prompt
SshDemo.exp
#!/usr/bin/expect
set prompt "#|>|\\\$ $"
spawn ssh dinesh@myserver
expect {
"(yes/no)" { send "yes\r";exp_continue}
"password"
}
send "welcome123\r"
expect -re $prompt
# Simply executing 'ls -l' command...
send "ls -l\r"
expect -re $prompt
log_user 0
send "logout\r"
expect eof
log_user 1
Related Topics
Linux Kernel "Historical" Git Repository with Full History
Fast Way to Get Image Dimensions (Not Filesize)
How to Shield a CPU from the Linux Scheduler (Prevent It Scheduling Threads Onto That Cpu)
How to Delete All Files Older Than 3 Days When "Argument List Too Long"
How to Know Which of the /Dev/Input/Eventx (X=0..7) Have the Linux Input Stream
Check Battery Level of Connected Bluetooth Device on Linux
Find Files in Created Between a Date Range
Best Practices for Git Repositories on Open Source Projects
I Want to Contribute to the Linux Kernel
Preserve Colouring After Piping Grep to Grep
Installing Node.Js on Debian 6.0
How to Kill Tcp Port 16969 in Bash
Ps Utility in Linux (Procps), How to Check Which CPU Is Used
Lsb_Release: Command Not Found in Latest Ubuntu Docker Container