How to expect multiple prompts correctly - regex

I have an expect script in which I am currently looking for multiple prompt types and sending commands in response. I am aware of regular expression matching using "-re" but I'd like to know of the correct way to achieve this.
For example, I have these prompt types:
[user#hostname ~]#
user#hostname --->
/ >
-bash-3.00$
cli>
Is this the correct/sufficient expression to detect all the above?
set multiPrompt "(%|#|cli\>|\$|\-\-\-\>)"
expect -re $multiPrompt
send "$someCommand\r"
Also, I have a list of commands, some of them cause the prompt to change after they are executed on the remote system. Due to the change in prompt, the remaining commands are not getting sent because my expect script is unable to detect the change and perform the send action.
What I'm trying to do is create a pool of possible prompts, so that my expect script sends the commands across without missing any of them. Is my approach correct?

While using a regular expression to detect the prompts is the right thing, choosing a good one is tricky when you've got such a wide range of possibilities. For example, I bet that this RE would work:
set multiPrompt {[#>$] }
(It just detects the end of the prompt, and ignores all the stuff before it. There's virtually always a space at the end of the prompt, used to visually separate what users type from the prompt.)
However, the problem is that this RE is fairly likely to match other things. You might instead be better off changing the prompt to a known-and-unique value (typically by setting the PS1 environment variable on the remote device) so that you get reliable detection. Mind you, that's only suitable when you're not exposing the prompts back to users, which is true for some uses of expect and not others…

I know it's an old thread, but for anyone searching on this I hope this helps. I am a UNIX sysadmin and have a handful of expect scripts my program calls on for various admin functions. This is the one solution I found that works in all my use cases:
set prompt "(%|#|>|\\$ )"
set prompt [string trim $prompt]
The [string trim $prompt] handles the scenarios where some prompts have a space before the input and some don't by trimming off the space when it looks at the prompt. Example: "password:" vs. "password: "

Related

Tab completion over ssh library

I am using paramiko library to connect with a specialized environment. Its based on linux but when we SSH in it provide its own shell. We can write help to get list of all commands that are supported in that session.
I am using paramiko with python2.7 to provide a CLI client (it automates few things) that connect with the host and let us run the supported commands. Now I would like to provide tab-completion in the client CLI. I am not sure how this can be done. I am thinking there would be some support or some specialize character that can be send to get back response but I am not sure how it can be accomplished.
I am hoping to avoid sending help command, parse the list of commands supported, and then provide a local tab-completion based on list of command. I want a more generic and dynamic solution.
Any or all ideas are welcome.
You can try simulating the partial input and the Tab key press and parsing the results, undoing the simulated input afterwards. But that is not a good idea. You will have to end up re-implementing terminal emulation, what is an insane task. Without a full terminal implementation, you can never be sure that you never get an output that you won't be able to parse.
The shell is a black box with input and output. It should only be used as such. You should never try to "understand" its output.
Using the help command is a way more reliable solution.

Python: Grab text printed to console

I'm using a complicated python module called CAMFR. In one function, it calculates a value that I want to use (to plot or otherwise), but unfortunately the module prints this value to the python console but doesn't return it as a variable!
(I have poked through the source code to see if I can recompile the module to return the values, but this looks excessively difficult at my programming level, considering it's written in C++ and uses Boost etc. I just don't get it unfortunately.)
SO, option number two is to grab the text printed to the console and parse out the value I need.
How can I intercept or otherwise acquire this function's console output text in Python (2.7)? (I will RegEx it afterwards.)
Thanks!
Here is an example of the text printed to the Python console:
<<a lot of other output, and then at the end of the function:>>
...
# 1.05554 4.65843e-05 5.54592 0.0903205 1
# 1.05554 2.87907e-05 3.42757 0.0903205 1
# 1.05554 2.87907e-05 3.42757 0.0903205 1
Done pass 1: lambda 1.05554, gain 3.42757
I ultimately want to grab the Lambda=1.05544 & Gain=3.42757 values, for example, and shove them into variables. Grabbing the entire console output of this one function would allow me to do that via a subsequent RegEx search, so I'm looking for a way to do that.
I apologize if there is another thread with the answer I need, I could not figure out google search terms that got me what I needed. Thanks for your patience & generous help!

Differentiating input and output color in Python in terminal

In review a particular session in python (that I execute via the terminal) I'd like to more easily differentiate between what i've typed in and what is returned after execution. Is there a way to change the colors of these?
Take a look at this answer. It's the only feasible way I see it doing what you're asking for. I don't think the terminal can decipher on its own what user input is.

C++ Windows - fill password field of system("run as")

I know there are many other ways to do this but I want to know how to fill in the password question of the windows the run as command automatically.
system("runas /user:\"benedikt\" \"xy.exe\"");
is there any way to do this? I googled a long time but i only found a lot of tools doing wat I want to do and not a way to do this for myself.
PS: I do not want to use any .Net functions.
OK, I'm going out on a limb here, because I'm not 100% sure that there isn't some (convoluted) way to achieve what you are looking for using stock runas. However, Why doesn't the RunAs program accept a password on the command line?, suggests there isn't - deliberately so to prevent "security issues" with plain-text passwords in command lines, batch files and tools that can view a command line (like Process Explorer).
BTW, a simple echo <password> | runas /user:<user> <command> doesn't seem to work either (it skips over the prompt for the password, but the password itself is not read by runas it seems).
So I guess you have to resort to some other means, like using the real API behind it all: CreateProcessWithLogin.

How can I login linux using C or C++

I need to programmely switch the current user to another,then the followed code should be executed in the environment(such as path,authority..) of another user.
I've find the 'chroot()','setuid()' may be associated with my case, but these functions need the root authority, I don't have root authority, but I have the password of the second user. what should I do?
I have tried shell "su - " can switch current user, can this command help me in my C++ code?
Don't laugh at me if my question is very stupid, I'm a true freshman on linux. :)
Thanks!
when clients connect to the server,
the server transfer the data what they
need,but the precondition is the
correct username and password.
If your primary requirement is to authenticate, then try man pam. There are also some libraries allowing to auth over LDAP. Unfortunately I have no personal experience implementing neither.
Otherwise, recreating complete user environment is unreliable and error prone. Imaging a typo or endless loop but in user's ~/.profile.
I haven't done that for some time, but I would also have tried to dig in direction of "su", figuring out user shell (from /etc/passwd) and trying to exec() it as if it was a login shell (with "-"). But after that you would need somehow to communicate a command for execution to it and that's a problem: shells run differently in batch more and in interactive mode. As a possible hack, expect (man expect) comes to mind, but it is still IMO too unreliable.
I have in past used ssh under expect (to input the password), but it was breaking on customized user profiles every other time. With expect, to send a command, one has to recognize somehow that shell has finished initialization (execution of profile and rc files). But since many people customize the shell prompt and their profile/rc files print extra info, it was quite often that expect was recognizing shell prompt too soon.
BTW, depending on number of users, one can try a setup where users manually start the server under their own account. The server would have access only to the information which is only accessible to the user.
You can use the system function to execute shell commands on the operating system.
You could take a look at the source code of the login command, or you could try using the exec()-family functions to call on login.
EDIT: Seems like you will need root access in any case.
Is setuid what you're looking for?
I think the key point here is that you can't change the user of the running process (easily). All the programs like 'su' are effectively starting a new process as the specified user.
Therefore, in your design I would recommend seperating off the functionality that needs to be done into a different executable and then investigate using execve() to start it.