Redirect string from bash stderr to user stdin

Hi there,

I need to execute a command in the bash. The program prints some standard (output and) error and then wants the user to choose one of several options and type the according input. I am trying to solve this issue in a bash script but also running into some circular dependency. How can I combine these two things to a single bash call with only one execution of command ? For the user input, i would usually write something like

echo $input | command

But $input must be read from stderr of command in advance which I would usually read as

input=$(command 2>&1 > /dev/null | awk '/some.*regexp$/ {print $2}')

I particularly don't want to execute command twice (once for extracting/saving the content of $input and once for feeding command with that input). Is there a way to combine the two calls in one? (BTW: both single commands work as I need them since I want to read from the stderr and don't need stdout at all.)

Many thanks in advance!

Welcome to the forum.

Your request is not clear. Be more specific and give more context.

command $(command 2>&1 > /dev/null | awk '/some.*regexp$/ {print $2}')

but that one-liner (which wouldn't work like that anyways) contains two calls of command . i would like to know, for several reasons, whether this can be done with a single call of command .

As has been said before, your request is not at all clear. If you would show us the output produced by command to its standard output and to its standard error and show us the output you are trying to produce, we would have a much better chance of helping you.

If you're saying that you want a bash script that you have named command is to read its own standard error output as part of its input, it might be impossible or it might be trivial depending on what your script is trying to do. If this is the case, we need to see the code in your script; not the way you are currently trying to invoke it. (And, the comments in your script had better be extremely clear about where the feedback loop is and what it is trying to do.)

Note that there is also a standard utility named command . Are you sure that you are invoking your script instead of the standard command utility??? The command utility is a shell built-in in bash , ksh , and many other shells based on Bourne shell syntax.

OK, I'm convinced and will try to explain in more detail. The command in question is called gmx genion from the Gromacs package for molecular dynamics simulations. When executing it in a bash terminal, it prints (using stderr) something like

Select a continuous group of solvent molecules
Group     0 (         System) has 51133 elements
Group     1 (        Protein) has  3961 elements
Group     2 (      Protein-H) has  1951 elements
Group     3 (        C-alpha) has   244 elements
Group     4 (       Backbone) has   732 elements
Group     5 (      MainChain) has   977 elements
Group     6 (   MainChain+Cb) has  1211 elements
Group     7 (    MainChain+H) has  1215 elements
Group     8 (      SideChain) has  2746 elements
Group     9 (    SideChain-H) has   974 elements
Group    10 (    Prot-Masses) has  3961 elements
Group    11 (    non-Protein) has 47172 elements
Group    12 (          Other) has    44 elements
Group    13 (            UNK) has    44 elements
Group    14 (          Water) has 47128 elements
Group    15 (            SOL) has 47128 elements
Group    16 (      non-Water) has  4005 elements
Select a group: 

expecting me to type one of the numbers and hit ENTER. I would always choose the number associated with the group SOL, hence 15 in this particular case. However, this number can vary and I want to automate this step in a bash script where, currently, I execute gmx genion twice:

groupselect=$(echo "" | gmx genion -s $manyArgs 2>&1 > /dev/null | awk '/ SOL\) has.*elements$/ {print $2}')
echo $groupselect | gmx genion -s $manyArgs 2>&1

The first line stores the string "15" in the variable called $groupselect whereas the second call executes the tool as desired with the content of $groupselect as input. Now, I would like to avoid one of the two calls to gmx genion . Is there a way to get this job done with a single call of gmx genion?

Thanks so far for your efforts!

If you want to script interaction with a program expecting human input, bash and most other shells are very bad at that. Pipes are poor substitutes for the interactive terminal the program is obviously expecting, they tend to deadlock with each process waiting for the other and no way to notify each other of said fact.

If your interaction is any more complicated than typing one number and hitting enter, you might look into the expect language, which is designed for these sort of problems. It will allocate a PTY which allows it to control the program it's communicating with asynchronously without all the piping and redirection.

this sounds far too complicated for me. it is indeed just typing a number and hitting ENTER, but trying to understand how to use for instance expect will cost me too much time i guess.

if someone already had a set of expect commands for that or some similar purpose, he could just paste it here and i would be grateful :slight_smile:

sorry for disturbing and many thanks anyway!