Data Capture Issue using expect in tcl - expect

I have one doubt in expect. I want to store the result of command in a string variable. Can anyone tell me what is the mistake in my code? It is not working. I have used expect_out(buffer) but its not working.
#!/usr/bin/expect
package require Expect
set Argu1 [lindex $argv 0]
set Argu2 [lindex $argv 1]
if {$argc == 2} {
if {[regexp {^(\d|[1-9]\d|1\d\d|2[0-4]\d|[2][5][0-5])\.(\d|[1-9]\d|1\d\d|2[
0-4]\d|[2][5][0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|[2][5][0-5])\.(\d|[1-9]
\d|1\d\d|2[0-4]\d|[2][5][0-5])$} $Argu1 match ]} {
puts "VALID IP-ADDRESS"
set timeout $Argu2-1
spawn ping $Argu1
expect "Expect"
set string $expect_out(buffer)
puts $string
puts "SUCCESS"
exit
} else {
puts "INVALID IP-ADDRESS"
}
} else {
puts "YOU HAVE TO GIVE TWO ARGUMENTS\n FIRST ARGUMENT SHOULD BE
IP-ADDRESS \n SECOND ARGUMENT SHOULD BE THE NUMBER OF PACKETS
YOU WANT TO SEND"
}

I'm reluctant to answer your question, as you haven't responded to my answer on another question. However, seeing as nobody else has responded, I'll try to help you out.
I don't think you need to use $expect_out(buffer) here. Assuming that a ping returning "0% loss" or "0% packet loss" means the ping was successful, you could try the following (untested). Obviously, you can change the "0%" to whatever you want to signify success.
#!/usr/bin/expect
package require Expect
set Argu1 [lindex $argv 0]
set Argu2 [lindex $argv 1]
if {$argc == 2} {
if {[regexp {^(\d|[1-9]\d|1\d\d|2[0-4]\d|[2][5][0-5])\.(\d|[1-9]\d|1\d\d|2[
0-4]\d|[2][5][0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|[2][5][0-5])\.(\d|[1-9]
\d|1\d\d|2[0-4]\d|[2][5][0-5])$} $Argu1 match ]} {
puts "VALID IP-ADDRESS"
set timeout $Argu2-1
spawn ping $Argu1
expect {
"0%" {puts "The IP address was successfully pinged"}
"default" {puts "Could not ping this IP address"}
}
exit
} else {
puts "INVALID IP-ADDRESS"
}
} else {
puts "YOU HAVE TO GIVE TWO ARGUMENTS\n FIRST ARGUMENT SHOULD BE
IP-ADDRESS \n SECOND ARGUMENT SHOULD BE THE NUMBER OF PACKETS
YOU WANT TO SEND"
}
The reason I suggest "0%" is as follows. If you do a successful ping from a Windows machine you will see something like this (note the "0% loss"):
C:\Documents and Settings\Brian>ping 192.168.1.1
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time=1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Ping statistics for 192.168.1.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 1ms, Average = 0ms
From a Unix machine, it might look like this (note the "0% packet loss") :
[brian#rex 4]$ ping -c 1 192.168.1.87
PING 192.168.1.87 (192.168.1.87) 56(84) bytes of data.
64 bytes from 192.168.1.87: icmp_seq=0 ttl=64 time=42.1 ms
--- 192.168.1.87 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 42.153/42.153/42.153/0.000 ms, pipe 2
You could pick many indicators of a successful ping, I chose the fact that there was a 0% loss of packets (a clear indicator of success). The expect command searches the result of the ping and if it finds "0%", it outputs "The IP address was successfully pinged".

Related

How to issue multiple commands to stdin in linux shell with <<<printf

I'm exercising with DVWA high level command injection. I know there is a hole for |, but I'm looking for a way to get an output like the following:
root#vwksOffensive:~# ping -c 4 10.0.0.1 ; ls
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
--- 10.0.0.1 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3066ms
a a_post Documenti Immagini Modelli Musica pocl rockyou.txt Scrivania WebScarab.properties
Add b hash JavaSnoop.properties mtu plain Pubblici Scaricati Video
root#vwksOffensive:~#
starting from
<<<printf "[ping ip argument] \u003B the_command_I_choose"
My problem is that can do this:
root#vwksOffensive:~# ping -c 4 <<<printf "10.0.0.1"
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
--- 10.0.0.1 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3055ms
root#vwksOffensive:~#
but I'm not able to do this:
root#vwksOffensive:~# ping -c 4 <<<printf "10.0.0.1 \u003b ls"
PING 10.0.0.1 \u003b ls (10.0.0.1) 56(84) bytes of data.
--- 10.0.0.1 \u003b ls ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3075ms
root#vwksOffensive:~#
and not even this:
root#vwksOffensive:~# ping -c 4 <<<printf "10.0.0.1 ; ls"
PING 10.0.0.1 ; ls (10.0.0.1) 56(84) bytes of data.
--- 10.0.0.1 ; ls ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3075ms
root#vwksOffensive:~#
I searched deeply and the most similar, if it could be said so, is the first answer to this question:
How to make a bash function which can read from standard input?
Unfortunately, this did not help me completely, so I decided to post here my question because I'm sure that, in my ignorance, I'm missing something.
The solution must contain the char ; or any other needed special char coded in unicode. The forbidden, substituted with blank, char are the following:
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
if the "command you choose" is in a variable like this:
mycmd="ls -l"
then you can wrap your command and other commands in a sub-shell surrounded by this: ( )
The output for the sub-shell can be re-directed into any other command that you want. e.g. tail, grep, > $log, etc.
The ip addresses that you want to send ping can also be in a variable name:
myip=10.0.0.1
(ping $myip ; $mycmd ) > logfile.txt
It is not clear why you would want to send it in with <<< instead of directly on the command line. If you must use <<<, then still try wrapping the commands in () parenthesis and put a carriage return after the <<< 10.0.0..
and the "ls -l". The parenthesis will tell bash that the command is not done until the closing parenthesis is seen. The carriage return will stop the <<< from consuming the next command.

Windows command line, how to filter with pipe

I'm trying to filter ping stats in windows command line using pipe. What I want is to get the 'time' of each ping.
"ping -n 1 -w 1000 " + ip
prints
Pinging 216.52.241.254 with 32 bytes of data:
Reply from 216.52.241.254: bytes=32 time=82ms TTL=240
Ping statistics for 216.52.241.254:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 82ms, Maximum = 82ms, Average = 82ms
The output I'm looking for from that would just be 82.
and my attempt with findstr "ping -n 1 -w 1000 " + ip + ' | findstr time=[0-9]*' prints:
Reply from 216.52.241.254: bytes=32 time=83ms TTL=240
The output should just be 83 this time.
I've tried using grep ?("time=")[0-9]*ms but on top of that line probably not being right I don't think windows grep includes conditionals

How to get output of ping command without Ping statistics?

For example, in Windows 7 output of command
ping -n 1 ::1
is following:
Pinging ::1 with 32 bytes of data:
Reply from ::1: time<1ms
Ping statistics for ::1:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
Is it possible to get output without Ping statistics (without the last four lines in this case or without two lines in case if destination host is unreachable)?
Maybe using this command:
ping -n 1 ::1 | find "string to search"
The currently accepted answer would filter out 'Request timed out' errors. Instead, use findstr /B R, which only outputs lines that start with R:
ping -n 1 ::1 | findstr /B R

Pinging 192.0.2.2 Receives a Response...but shouldn't

I'm using the windows batch script function ping 192.0.2.2 -n 1 -w 10000 > nul on my local machine (Windows 7) in a command prompt to test its functionality. The explanation of the function is here: "How to wait in a batch script?".
I've used 192.0.2.2 because it is considered a reserved IP address, so there should be no response. But instead, my results are inconsistent - sometimes I get a response with the error "Destination net unreachable."
C:\Users\MrF>ping 192.0.2.2 -n 1 -w 10000
Pinging 192.0.2.2 with 32 bytes of data:
Reply from 10.10.251.2: Destination net unreachable.
Ping statistics for 192.0.2.2:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
C:\Users\MrF>ping 192.0.2.2 -n 1 -w 10000
Pinging 192.0.2.2 with 32 bytes of data:
Request timed out.
Ping statistics for 192.0.2.2:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
C:\Users\MrF>ping 192.0.2.2 -n 1 -w 10000
Pinging 192.0.2.2 with 32 bytes of data:
Request timed out.
Ping statistics for 192.0.2.2:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
C:\Users\MrF>ping 192.0.2.2 -n 1 -w 10000
Pinging 192.0.2.2 with 32 bytes of data:
Request timed out.
Ping statistics for 192.0.2.2:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
C:\Users\MrF>ping 192.0.2.2 -n 1 -w 10000
Pinging 192.0.2.2 with 32 bytes of data:
Reply from 10.10.251.2: Destination net unreachable.
Ping statistics for 192.0.2.2:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
C:\Users\MrF>ping 192.0.2.2 -n 1 -w 10000
Pinging 192.0.2.2 with 32 bytes of data:
Request timed out.
Ping statistics for 192.0.2.2:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
C:\Users\MrF>
Unfortunately, the function only waits 10 seconds when the ping is lost. Pings that receive a response don't wait at all. This has lead to some frustrating lack of functionality in my scripts that require wait commands. How can I fix this? Why is it happening?
That is not a link local or LAN reserved IP range, but it is routable (although no one should ever route to it). See this whois info for full details. A link local 169.254 range IP would give more consistent, reliable results. See this answer for further explanation.
Edit: I see what you mean. Even my previous 169.254 solution is subject to the same inconsistency. Well, really, the biggest benefit to pinging a bogus IP with the -w switch is so you can pause in milliseconds. If you're pausing in whole seconds (such as ten seconds in your example above), just
ping -n 11 localhost >NUL
... where 11 is N+1 seconds to pause. That command will pause for 10 seconds.
Alternatively, you could use the timeout /t 10 /NOBREAK >NUL command if your script will be run on Vista or newer.
If you need fraction-of-a-second pausing, you could always employ VBScript or JScript.
#if (#CodeSection == #Batch) #then
#echo off
setlocal
set /P "=Pausing 1.5 seconds."<NUL
call :sleep 500
set /P "=."<NUL
call :sleep 500
set /P "=. "<NUL
call :sleep 500
echo Done.
goto :EOF
:sleep <milliseconds>
cscript /nologo /e:JScript "%~f0" "%~1"
goto :EOF
#end // end Batch / begin JScript
WSH.Sleep(WSH.Arguments(0) * 1);
Windows has many wait commands, I use waitfor. But there is choice and timeout as well.
Maybe stop searching the internet. Ping is a silly idea. What would happen if all 175,000 computers at my work all started pinging at the same time.
waitfor /t 99999 Fred

open CMD window and run command

The following VB script open CMD window and perform ping to IP – 127.0.0.1
I don’t understand why the output from the CMD window include only the results from ping and not also the “ping 127.0.0.1” ?
My question what need to change in my VB script in order to see also the ping command from the CMD window and not only the ping results ?
My VB script:
Dim oShell
Set oShell = WScript.CreateObject ("WScript.Shell")
oShell.run "cmd /k CD C:\Program Files & ping 127.0.0.1 " ,1 , true
what I see from CMD is only that: ( ping 127.0.0.1 not apears ? )
Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Ping statistics for 127.0.0.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
"ping 127.0.0.1" is a batch file command. If you hit the start button, type "command prompt", open up command prompt and type that command then you'll get an output along the lines of what I got.
Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL-128
Reply from 127.0.0.1: bytes=32 time<1ms TTL-128
Reply from 127.0.0.1: bytes=32 time<1ms TTL-128
Reply from 127.0.0.1: bytes=32 time<1ms TTL-128
Ping statistics for 127.0.0.1:
Packets: Sent = 4, Received = 4, lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

Resources