Send command while expect can get specific text - expect

I Have one problem when i am using expect.
I need to list some information.
But the program list 10 items and then shows (More...) and waits a key
So:
expect "More..."
send "\n"
But the program shows more 10 lines and does it again, i can track how many times i need to do that, but the list changes a lot.
Is there a way to do something like:
while expect "More..." do
send "\n"
done
I know the expect waits for a string, is there some kind of "hit" command?
Thanks

You want exp_continue and the block form of expect:
expect {
"More..." {
send "\n"
exp_continue
}
"something else to expect for"
}

Related

How can I make down arrow key be effective in shell(or expect) script

I am writing scripts for automate 'make menuconfig'.
I want to use down arrow key to select some items in the dialog.
My down arrow key in terminal is '^[[B'.
So I use send "\033[B", send "\x1b\x5b\x42", send "\1B[B", etc. in expect script,
but none is working.
#!usr/bin/expect
spawn make menuconfig
send "v" #select item hot key
send "y" #enter this item
send "\033\[B" #I expect the down arrow key will execute here.
interact
exit 0
How could I do?
Or does this not work in expect?
Is there other method to automate do this?

Gets stops processing script if it encounters a apostrophe

I'm futzing with a lesson over on Codecademy, pretty basic but the lesson prompts the user for a string and then prompts them for words to hide from the string. I've already finished with the lesson but I wanted to try messing with it outside of the lesson.
What I'm finding is the following script will run to completion in the lesson's scripting and interpreter area but if I try to run the same script over at say labs.codecademy.com or repl.it
I'll get prompted for the first question and if I enter a string containing an apostrophe it won't go on to the next prompt. I'm not getting an error, but eventually I'll get a "This program is taking too long to finish" pop up.
Here's the script:
puts "Tell me something."
text = gets.chomp
puts "What would you like me to forget?"
redact = gets.chomp
words = text.split(" ")
words.each { |text|
if redact.include? text
print "REDACTED "
else
print text + " "
end
}
So for example if you were to enter I really like blueberry pie that passes, but if you were to enter They've told me I should try the blueberry pie the program gets hung up.
I'm a complete novice when it comes to Ruby, but is there a way to have gets process that sort of punctuation? Or is that not the right way to go about it? Or is it just the environment I'm trying to run this program in?
IO.gets is a system-level call: http://apidock.com/ruby/IO/gets
it well read from STDIN (standard input) which is the text that you type in a terminal window: http://en.wikipedia.org/wiki/Standard_streams
browsers per-se don't have this and it might depend on the implementation of the web-based console about how they handle calls like that. usually, there are known limitations (like this one).
as #BroiStatse pointed out, it might as well be a bug in in their browser-based implementation.

How can I make an applescript controlled iMessage reply differently?

I have been coding my own version of Jarvis in Applescript for a few days now, I have been using iMessages as my input and output as I love the way its portable, yet I now want to get a bit more advanced and start making it feel like it has a use.
Currently I just use simple lines of code to recognise when I send something and then run the appropriate script to send a reply. Such as, If I say "hello", it says "hello sir" back to me.
An example being:
using terms from application "Messages"
on message received theMessage from theBuddy for theChat
if theMessage is "hello" then
run script ("/Users/Alex/Desktop/JarvisScripts/hello.scpt" as POSIX file)
end if
end message received
end using terms from
All good, but I as I said before I want to go further, I need a way it can ask me a question such as "how are you", and then depending on what I say back such as "good" it will run the right scripts to respond to "good".
My current attempts go along the lines of:
if theMessage contains "Are you ok" then
run script ("/Users/Alex/Desktop/JarvisScripts/areyouok.scpt" as POSIX file)
if theMessage is "I'm fine" then
run script ("/Users/Alex/Desktop/JarvisScripts/happy.scpt" as POSIX file)
else
if theMessage is "No I'm not" then
run script ("/Users/Alex/Desktop/JarvisScripts/unhappy.scpt" as POSIX file)
end if
end if
end if
But I know this is far from correct. So, can anybody help me with some code? Thanks
Instead of storing your 'responses' in separate script files. Try using a handler instead.
For example:
if theMessage contains "Are you ok" then
run script ("/Users/Alex/Desktop/JarvisScripts/areyouok.scpt" as POSIX file)
if theMessage is "I'm fine" then
happyResponse()
else
if theMessage is "No I'm not" then
unhappyResponse()
end if
end if
end if
--HANDLERS--
on unhappyResponse()
--<<whatever you want to happen (the code inside your .scpt file)>>
end unhappyResponse
on happyResponse()
--<<put the contents of happy.scpt here>>
end happyResponse
As you can see, the 'handlers' are listed at the bottom of your code and whenever one of the functions are called, code is evaluated for them. Now I don't know what is inside of your .scpt files but this should work in most uses.

Multi-line input problems when using STDIN.gets

Having looked at this question, I have the following code:
$/ = "\0"
answer = STDIN.gets
Now, I was hoping that this would allow the user to:
enter a multi-line input, terminating by pressing Ctrl-D.
enter a single line input, terminating by pressing Ctrl-D.
enter a "nothing" input, terminating by pressing Ctrl-D.
However, the behaviour I actually see is that:
The user can enter a multi-line input fine.
The user can not enter a single line input, unless they hit Ctrl-D twice.
The user can enter a "nothing" input if they hit Ctrl-D straight away.
So, why does the single line situation (i.e. if the user has entered some text but no newline and then hit Ctrl-D) require two presses of Ctrl-D? And why does it work then if the user enters nothing? (I have noted that if they enter nothing and hit Ctrl-D, I don't get an empty string but the nil class - I discovered this when trying to call .empty? on the result, since it suddenly failed horribly. If there is a way to get it to return an empty string as well, that would be nice. I prefer checking .empty? to ==, and don't particularly want to define .empty? for the nil class.)
EDIT: Since I really would like to know the "correct way" to do this in Ruby, I am offering a bounty of 200 rep. I will also accept answers that give another way of entering terminal multi-line input with a sensible "submit" procedure - I will be the judge of 'suitable'. For example, we're currently using two "\n"s, but that's not suitable, as it blocks paragraphs and is unintuitive.
The basic problem is the terminal itself. See many of the related links to the right of your post. To get around this you need to put the terminal in a raw state. The following worked for me on a Solaris machine:
#!/usr/bin/env ruby
# store the old stty settings
old_stty = `stty -g`
# Set up the terminal in non-canonical mode input processing
# This causes the terminal to process one character at a time
system "stty -icanon min 1 time 0 -isig"
answer = ""
while true
char = STDIN.getc
break if char == ?\C-d # break on Ctrl-d
answer += char.chr
end
system "stty #{old_stty}" # restore stty settings
answer
I'm not sure if the storing and restoring of the stty settings is necessary but I've seen other people do it.
When reading STDIN from a terminal device you are working in a slightly different mode to reading STDIN from a file or a pipe.
When reading from a tty Control-D (EOF) only really sends EOF if the input buffer is empty. If it is not empty it returns data to the read system call but does not send EOF.
The solution is to use some lower level IO and read a character at a time. The following code (or somethings similar) will do what you want
#!/usr/bin/env ruby
answer = ""
while true
begin
input = STDIN.sysread(1)
answer += input
rescue EOFError
break
end
end
puts "|#{answer.class}|#{answer}|"
The results of running this code with various inputs are as follows :-
INPUT This is a line<CR><Ctrl-D>
|String|This is a line
|
INPUT This is a line<Ctrl-D>
|String|This is a line|
INPUT<Ctrl-D>
|String||

Threading In Shoooes

Is it possible from within shoooes to spawn a separate thread which will read from a named pipe and then print whatever is written in that name pipe into a text box? Would anyone have an example of how to set that up?
It's pretty easy to manipulate text across threads. Try this code, for example:
Shoes.app do
#text = para 'Do you like ponies?'
Thread.new do
sleep(4)
#text.text += " Of course I do!"
end
timer(2) {#text.text += "\nWhat a silly question."}
end
As to reading from a named pipe, they can be treated like any other file, with the caveat that they will block until the other side of the pipe is set up. So, either make them non-blocking or just set the other side up before you open the pipe.

Resources