Prompt detection in scripting when the prompt is variable

0 votes
asked Jan 24 by ioan.crisan (400 points)

I need to execute scripts using SSH and Scripting. Each script is split into commands and executed individually, evaluating the output for each command. To identify the output, I use ReadUntilPrompt(). Before issuing any command, I call DetectPrompt() once.

However, some customer has a very dynamic prompt, containing some kind of counter, which makes ReadUntilPrompt() unreliable. After a lot of troubles I ended up simulating a constant prompt (a GUID) which is issued as an echo command after each proper command, and I read until this GUID is matched (ReadUntil(GUID)). This is less than satisfactory, but it works, provided my script builder does not switch the shell in his scripts to sqlplus, for example. This latter case should also be supported, but here end my ideas.

Example of a combined shell script:

echo Entering SQL scripting
sqlplus username/password@123.45.67.111:1521/SID123
select * from sales;
quit
echo Back again in the shell

Could you help me with some ideas/samples in this area? Thanks!

1 Answer

0 votes
answered Jan 25 by Pavel Matyska (12,000 points)
selected Jan 25 by ioan.crisan
 
Best answer

Hello,

you can set scripting.Prompt directly. You can make up some regular expression that will match the prompt with the counter, such as

scripting.Prompt = @"regex:PromptWithCounter[\d+]";

You can also change the Propmt property when you know the actual prompt will change after a command. For example if you know that you will get "> " as a prompt after calling 'sqlplus' command, you can change it before reading until prompt.
You can also make that regex more complex to handle both cases but make sure that it will not interfere with any command output.

Our DetectPrompt method is made so it send empty commands (just ENTER) and checks lines on the screen whether the last two are the same or not. You can expand on this idea to came up with the regex and then set it to the scripting.Prompt property. Please note that regex prompt have to have "regex:" prefix as you can see in my example above.

commented Jan 25 by ioan.crisan (400 points)
Thanks for the clarification. However, in my situation there are some variables that I cannot control:

* The prompt with the counter is only one example. Some administrators set it to the current date and time, so I cannot really infer a generic rule to make up a regex.
* The switch to different shells (like the sqlplus one) is hard to handle.

However, I imagine you cannot provide a solution to all these cases, even if it would be great, and thanks for the answer!
commented Jan 28 by Pavel Matyska (12,000 points)
Hello,

I meant by my last paragraph that you try to write an algorithm to generate some regex which will match a prompt. And the result of this algorithm would be set to scripting.Prompt property.

"The switch to different shells (like the sqlplus one) is hard to handle" ... do you mean that you do not know what script you will be running? So you cannot "predict" that the prompt will change?

You can also utilize ScriptEvent.Delay(int milliseconds) which will match when no data are received for specified time. It will slow down processing of your scripts because after each command you will wait the specified time, but you will not mess with the prompt at all. I know this is not an elegant solution but if you can have different prompt after each command, literally, this may be a solution for you.
...