I am trying to match a prompt but the OR statement inside parenthese (%|#) is not working.
The following is WORKING only for % ending prompts and NOT WORKING with # ending prompts :
set FULLPROMPT "${HOST} (.+)(%|#) $"
The following is NOT WORKING at all for any prompt :/ :
set FULLPROMPT "${HOST} (.+)% $"
I am missing something obviously.
The prompts can be like this
12:33 user#hostname ~%
12:33 root#hostname /usr/local/folder#
Expect is running as
set HOST "hostname"
set FULLPROMPT "${HOST} (.+)(%|#) $"
send "\n"
expect -re $FULLPROMPT
Any help would be greatly appreciated
Thanks to Schelte Bron, I now can see exactly how the regex matches the prompts.
It turns out that the prompt has colors and this put all sort of characters before and after the % or #.
To overcome this you can either
overide the prompt PS1 variable
take care of all the hidden characters of the prompt in the regex
capture the prompt when logging in and use it in the regex (seems like what we SHOULD do but this seems a lot of work)
Run expect in debug mode :
expect -d
Related
I'm working with expect scripting in order to ssh into a device and pull information off of it. However, I'm facing issues parsing the expect_out(buffer) for the data from the commands I send.
This is the contents of my expect_out(buffer):
"mca-cli-op info\r\n\r\nModel: UAP-AC-Lite\r\nVersion: 6.0.21.13673\r\nMAC Address: 10:9f:5r:20:c5:7e\r\nIP Address: 123.123.1.123\r\nHostname: UAP-AC-Lite\r\nUptime: 152662 seconds\r\n\r\nStatus: Connected (http://base_controller<url;>/inform)\r\nUAP-AC-Lite-BZ.6.0.21# "
Right now I'm trying to get the Model (UAP-AC-LITE) without the Model tag.
So the regex expression I'm using is,
expect -re {(?=(Model: ))+[.*\$]}
set model "$expect_out(0,string)"
puts $model
The command doesn't work, but my thought process was that I would perform a look ahead for the Model tag, then match only the subsequent characters after it to the new line. I've tried replacing the "$" with \r\n but that doesn't work either. Can anyone explain what I'm doing wrong? Thanks for the help!
Note: If possible, I wouldn't want to include the newline either, as it might mess up commands that I run which use these variables.
You're close, but the regex is incorrect. Try
expect -re {Model:\s+([^\r]+)}
set model $expect_out(1,string)
The 1 in $expect_out(1,string) means the first set of capturing parentheses.
Regexes are documented at http://www.tcl-lang.org/man/tcl8.6/TclCmd/re_syntax.htm
I am running some commands in pexpect session where it gives the following output in console.
this is the first line output
\u0000>\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000
I am having a regex '\r\n>' to match the prompt '>' at the new line.
From the output I can see there is one control character \u0000 is prefixed before the prompt comes
\u0000>\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000
My code goes like
child = pexpect.spawn('/bin/bash')
child.sendline(command)
child.expect('\r\n>')
Because of this control character prefixed before the prompt, the expect is failing. Is there any way to solve this issue.
Logically we can see the prompt came in next line, but literally how we can match along with control character?
Do i need to modify my regex to match "controlchar\r\n>"? or any other way to solve this issue?
I'm trying to create an AppleScript to delete messages conversations that match a particular regex pattern. I tried to follow an example I found, but it seems to be using code that no longer works (perhaps High Sierra limitations).
The following is the code doesn't seem to work.
set chatsToKill to {}
tell application "Messages"
set allChats to every chat
repeat with eachChat in allChats
--
-- The example fails because ScriptEditor would error saying it could get participants of the value returned for the first (or any of eachChat).
--
set thePeeps to participants of eachChat
repeat with oneParticipant in thePeeps
set theHandle to handle of oneParticipant
try
do shell script "echo " & quoted form of theHandle & " | egrep '^SMS;-;141'"
if chatsToKill does not contain eachChat's id then set end of chatsToKill to eachChat's id
end try
end repeat
end repeat
repeat with deathChat in chatsToKill
-- This should be a delete of the deathChat
end repeat
end tell
Perhaps things have changed since that script was written, but it is flawed and will not work, and I'm not sure it can be made to work as of macOS 10.11.6+.
Apple has greatly limited scripting access to the Messages app.
When I step through your script, I get an error on this line:
set thePeeps to participants of eachChat
The error is:
Messages got an error: Can’t get participants of text chat id
"iMessage;-;+1123121234".
Even when I put the code in a try/catch block, it failed for all messages.
Even if that worked, I don't see how the remainder of your script would work. You execute a do shell script without assigning the results to anything.
You need something like this:
set scriptResults to do shell script "echo " & quoted form of theHandle & " | egrep '^SMS;-;141'"
-- do something with scriptResults
if chatsToKill does not contain eachChat's id then set end of chatsToKill to eachChat's id
Sorry I can't offer something better.
I have a script that outputs a serials.txt file like this:
Serial Number
88PRDQ1
Serial Number
CZSQZV1
I would like to capture the service tag in a variable for future manipulation in the script.
My code seems to fail entirely and I can't find much in the way of what I am looking for with FINDSTR.
for /f "delims=" %%S in (serials.txt) do (findstr /r "^......[^ ]")
Since the output can be 6-7 long and any letter or number, I am struggling to get it to behave properly. It runs forever at the moment and I am unsure how to output the result to a variable and act on it if I somehow managed to get this line correct.
The [^ ] is meant to exclude spaces but accept anything else so as to not print the line that says "Serial Number" in the event of a 6 char serial.
What am I missing?
findstr /v /c:"Serial Number" serials.txt|findstr "."
First finds all line not containing the string "Serial Number", then filters any line containing at least one character to suppress empty lines.
I am trying to automate the configuration of a server using perl and the expect module. I have been using the expect module three days but now I have encountered a problem that I can't solve.
My problem is when im executing a command that prints no output if it is successful but prints an error message if something went wrong. An example of such command is the cd command:
$ cd .
$
$ cd sadjksajdlaskd
sadjksajdlaskd: No such file or directory.
$
What I would like to do is to send the command to the server, and then perform an expect call to check if something other than the prompt sign was printed. Something like this:
$com->send("cd $dir");
$com->expect(2,
["^[^$#]*", sub {
my $self = shift;
my $error = $self->match();
die "ERROR: $error";
}],
"-re", "^[$#]"
);
The problem I have is that when I perform the expect call it will match against all previous text and not against text received after the send call, so it will always match and report an error. How do I make expect match only agains the text received after the send call? Is it possible to clear the buffer of the expect module or is it possible to achieve this kind of error detection some other way?
I also wonder how the expect module handles regular expressions. If I for example use "^[$#]\$" as the regular expression to match the prompt of the terminal, will the \$ part of the regular expression match end of line or an actual dollar sign? If i remove the \ perl complains.
Thanks in advance!
/Haso
EDIT: I have found a solution:
The solution was to use $com->clear_accum() which clears the accumelator. I have tried using it before but it seems like this function only works at random, or maybe I don't understand what clear_accum() is suppose to do.
EDIT: A final note about clear_accum():
The reason the clear_accum() function seems to work at random is because the text generated from the previous send is not read into the accumelator until an expect() call is made. So in order to truly clear all previous data is to first perform an expect() call and then clear the accumelator:
#To clear all previous data
$com->expect(0);
$com->clear_accum();
akarageo#Pal4op:~> cd banana
bash: cd: banana: No such file or directory
akarageo#Pal4op:~:( > echo $?
1
i.e. check the error code that CD returns, 0 means OK anything else is an error, No need to check the prompt , and btw, the CD command does not generate the prompt the shell does, so that must be part of your confusion also.
try $object->exitstatus() if it is of any help