Run exe in sh script and press keys if needed [duplicate] - bash

This question already has answers here:
Passing arguments to an interactive program non-interactively
(5 answers)
Closed 2 years ago.
I need to write a bash script that runs some console application with arguments, lets say app.exe -arg. The problem is, that program while it's working, asks user to press some key e.g. press o for OK or c for Cancel. I need to scan output at all times for such expressions and press certain keys when needed. Ideally I would have a set of rules that whould apply to the whole output for the whole time, and when expression 1 is found, do this, when expression 2 is found in output, do that (like press some key) and allow output to be examined further the same fassion. Until some "ending expression" is found, then close script. Im kinda newbie in bash scripting. Any help?

expect is the answer to your question. It allows you to automate such procedures:
wait for a certain phrase
provide input
...

Related

Lua: Cannot open : Invalid argument [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Well I've recently decided to start learning lua and I have some problems executing code in Sublime Text 3 although everything works fine in command line
The error output shows you, in order:
The output from the program that was executed
How long the operation took, and what the exit code was
The exact command that was executed
The directory that was the "current working directory" while the program was running
The PATH environment variable, so that if there was a problem finding the command to execute you can see where it looked.
If you look at the third item there, the command that was executed, it's:
[cmd: ['lua', '']]
This means that it tried to execute the command 'lua' with an empty second argument. The reason for that is that you didn't save your file before you tried to run it; thus is has no associated file name to give to the command.
Saving the file first will solve the problem. The Tools > Save all on build option (when checked) will make sure that all unsaved changes are persisted to disk before the program runs, but this only works for files that have already been saved at least once.

Why is writer of os/exec.StderrPipe closed in Start()?

Can someone help me understand why pw (the writer) is scheduled for closing in Start()?
I would expect pw to be closed together with pr ( the reader) in Wait().
closeAfterStart and closeAfterwait are two slices of io.Closers which are called respectively ins Start and Wait of cmd Struct. Now, why is this? both these are basically buffers(slices) which either need to be written into read off of. Depending on whether they are currently in use, they are closed. for example StdInPipe requires reading first and then writing to, therefore the pr is included in closeAfterStart and pw in closeAfterWait. The reverse is done for StdOutPipe.
The program is simply closing off the buffers which it doesn't need anymore in the code. In StdErrPipe the function is called after execution of command, to write the error output to some output. So, the program already has the output it needs to write.

Start a program not as a child process

I am trying to run a program from cmd, but not as a child of the prompt. I have tried calling the program directly: program, but this starts it as a child process. I have tried start "" program, but this also starts it as a child process. Is this possible? I don't want the program to close when the prompt is closed.
Edit: This is not a duplicate question - start doesn't work in this case. I don't know enough to explain better, but some things to note:
The program in question doesn't open a new window
The path to the program contains spaces, so requires inverted commas. However, the inverted commas seem to suggest to start that the argument is intended to be the name of the new command window.
I need to pass switches to the program, which makes things a bit more complicated

Bash: how to duplicate input/output from interactive scripts only in complete lines?

How can I capture the input/ output from a script in realtime (such as with tee), but line-by-line instead of character-by-character? My goal is to capture the input typed into the interactive prompts of a script only after backspaces and auto-completion have finished processing (after the RETURN key is hit).
Specifically, I am trying to create a wrapper script for ssh that creates a timestamped log of commands used on remote servers. The script, which uses tee to redirect the output for filtering, works well, but the redirected output gets jumbled with unsubmitted characters whenever I use the backspace key or the up/down keys to scroll through my remote history. For example: service test stopexitservice test stopart or cd ..logs[1Pls -al.
Perhaps there is a way to capture the terminal's scrollback and redirect that like with tee?
Update: I have found a character-based cleanup solution that does what I want most of the time. However, I am still hoping for an answer to this question (which may well be msw's answer that it is very difficult to do).
In the Unix world there are two primary modes of handling keyboard input. These are known as 'raw' in which characters are passed from the terminal to the reading program one at a time. This is the mode that editors (and such) will use because the editor needs to respond immediately when you press a key.
The other terminal discipline is called 'cooked' which is the line by line behavior that you think of as the bash line by line input where you get to backspace and the command is not executed until you press return. Ssh has to take your input in raw, character-by-character mode because it has no idea what is running on the other side. For example, if you are running an editor on the far side, it can't wait for a return before sending the key-press. So, as some have suggested, grabbing shell history on the far side is the only reasonable way to get a command-by-command record of the bash commands you typed.
I oversimplified for clarity; actually most installations of bash take input in raw mode because they allow editor like command modification. For example, Ctrl-P scrolls up the command history or Ctrl-A goes to the beginning of the line. And bash needs to be able to get those keys the moment they are typed not waiting for a return.
This is another reason that capturing on the local side is obnoxiously difficult: if you capture on the local side, the stream will be filled with Backspaces and all of bash's editing commands. To get a true transcript of what the remote shell actually executed you have to parse the character stream as if you were the remote shell. There also a problem if you run something like
vi /some_file/which_is_on_the_remote/machine
the input stream to the local ssh will be filled with movement commands snippets of text including backspaces and so on and it would be bloody difficult to figure out what is part of a bash command and what is you talking to the editor.
Few things involving computers are impossible; getting clean input from the local side of an ssh invocation is really, really hard.
I question the actual utility of recording the commands that you execute on a local or remote machine. The reason is that there is so much state which is not visible from a command log. As a simple example here's a log of two commands:
17:00$ cp important_file important_file.bak
17:15$ rm important_file
and two days later you are trying to figure out whether important_file.bak should have the contents you intended or not. Given that log you can't answer that simple question. Even if you had the sequence
16:58$ cat important_file
17:00$ cp important_file important_file.bak
17:15$ rm important_file
If you aren't capturing the output, the cat in the log will not tell you anything. Give me almost any command sequence and I can envision a scenario in which it will not give you the information you need to make sense of what was done.
For a very similar purpose I use GNU screen which offer the option to record everything you do in a shell session (INPUT/OUTPUT). The log it creates also comes with undesirable characters but I clean them with perl:
perl -ne 's/\x1b[[()=][;?0-9]*[0-9A-Za-z]?//g;s/\r//g;s/\007//g;print' < screenlog.0
I hope this helps.
Some features of screen:
http://speaking-my-language.blogspot.com/2010/09/top-5-underused-gnu-screen-features.html
Site I found the perl-oneliner:
https://superuser.com/questions/99128/removing-the-escape-characters-from-gnu-screens-screenlog-n

What level of expertise would this interview item suggest? unset foo; echo bar | read foo; echo $foo [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Imagine that you are preparing for an in-depth technical interview and you are asked to rate your expertise in shell scripting (hypothetically on a scale of one to ten). Then look at the following shell command line example and answer the questions: What does this do? and Why?
unset foo; echo bar | read foo; echo "$foo"
What level of expertise would you map to correctly answer this question for the general case (not merely for one or another, specific, version of the shell)?
Now imagine that you're given the following example:
cat "$SOMELIST_OF_HOSTS" | while read host; do ssh $host "$some_cmd"; done
... and the interviewer explains that this command "doesn't work" and that it seems to only execute the ssh command on a few of the hosts listed in the (large) file (something like on in every few hundred hostnames, seemingly scattered from among the list). Naturally he or she asks: Why is it doing that? and How might you fix it?
Then rate the level of expertise to which you would map someone who can answer those questions correctly.
The first one is novice intermediate (see below) level. unset, echo, read and basic variable use should be encountered within the first 1000 lines of Bash or so, working on typical shell code.
The second is intermediate level IMO; I'd been using Bash for some years before I found out about innocuous commands like ssh gobbling standard input. It's a good test for the ssh command specifically, but since it's a bit of an anomaly it might be better to test with simply cat to see if the candidate understands the basis of the problem.
But as I think #IgnacioVazquez-Abrams is pointing out, you can't rate much based on just two narrow questions - As others have pointed out, why not just give them an actual issue to work on? You'll get an infinitely better idea of their ability to actually get work done.
Edit: As #IgnacioVazquez-Abrams also pointed out, these essentially test the same thing. So I'd rate both intermediate.
Note that the first example is dependent on the shell. The pipe is an IPC (inter-process communications) operator and the shell can implement that by creating a subshell on either side of the pipe. (Technically I suppose some shell could even evaluate both sides in separate sub-processes).
The read command is a built-in (must, inherently be so). So, in shells such as bash and the classic Bourne shell derivatives the suprocess (subshell) is on the right of the pipe (reading from the current shell) and that process ends after its read (at the semicolon in this example). Korn shell (at least as far back as '93) and zsh put their subshell on the other side of the pipe and are reading data from those into the current process.
That's the point of the interview question.
The point of my question here is to look for some consensus or metric for how highly to rate this level of question. It's not a matter of trivia because it does affect real world scripts and portability for shell scripting and it relies upon fundamental understanding of the underlying UNIX and shell semantics (IPC, pipes, and subprocesses/subshells).
The second example is similar but more subtle. I will point out that the following change "works" (the ssh will execute on each of the hosts in the file):
cat $SOME_FILE | while read host; do ssh "$host" "$some_cmd" < /dev/null; done
Here the issue is that the ssh command buffers up input even if the command on the remote never reads from its stdin. Because the shell/subshell (reading from the pipe) and the ssh are sharing the same input stream, the ssh is "stealing" most of the input from the pipeline, leaving only the occasional line for the read command.
This is not an artificial question. I actually encountered it in my work and had to figure it out. I know from experience that understanding this second example is at least a notch or two above the first. I also know, also from years of experience, that fewer than 10% of the candidates (for sysadmin and programming positions) that I've interviewed can get the first question right away).
I've never used the second question in a live interview and I've been discouraged from doing so.

Resources