Upon creating the index file with gmx make_ndx, we are usually prompted with interactive shell.

For example:

$ gmx make_ndx -f em.gro -o index.ndx

Will give:

  0 System              : 120070 atoms
  1 Protein             :  7132 atoms
  2 Protein-H           :  3818 atoms
  3 C-alpha             :   500 atoms
  4 Backbone            :  1500 atoms
  5 MainChain           :  2001 atoms
  6 MainChain+Cb        :  2463 atoms
  7 MainChain+H         :  2472 atoms
  8 SideChain           :  4660 atoms
  9 SideChain-H         :  1817 atoms
 10 Prot-Masses         :  7132 atoms
 11 non-Protein         : 112938 atoms
 12 Other               :   446 atoms
 13 PEP                 :   446 atoms
 14 NA                  :   156 atoms
 15 CL                  :   112 atoms
 16 Water               : 112224 atoms
 17 SOL                 : 112224 atoms
 18 non-Water           :  7846 atoms
 19 Ion                 :   268 atoms
 20 PEP                 :   446 atoms
 21 NA                  :   156 atoms
 22 CL                  :   112 atoms
 23 Water_and_ions      : 112492 atoms

 nr : group      '!': not  'name' nr name   'splitch' nr    Enter: list groups
 'a': atom       '&': and  'del' nr         'splitres' nr   'l': list residues
 't': atom type  '|': or   'keep' nr        'splitat' nr    'h': help
 'r': residue              'res' nr         'chain' char
 "name": group             'case': case sensitive           'q': save and quit
 'ri': residue index

Then manually I have to do this:

# Choosing "1 Protein" and "13 PEP" when prompted
> 1 | 13
> q

How can I by-pass that by issuing just one command line? I tried this but failed:

$ echo "1 | 13" | gmx make_ndx -f em.gro -o index.ndx
  • $\begingroup$ I tried this: echo -e "0 & ! a H*\n q"| gmx make_ndx -f lig.pdb -o index_lig.ndx but this throws, syntax error. then i tired the followed one. it works fine. echo "0 & ! a H*\n q"| gmx make_ndx -f lig.pdb -o index_lig.ndx $\endgroup$ Commented Feb 24, 2022 at 10:00
  • $\begingroup$ @ManivannanS echo -e is not POSIX compliant and so it will vary what systems will use that syntax. Most shells should allow echo to expand escape characters by default (as your working example does), as described in this comment on Linux&Unix $\endgroup$
    – Tyberius
    Commented Feb 24, 2022 at 20:21

3 Answers 3


Note: there's nothing specific to Gromacs in the answer below. These are just shell scripting techniques that are relevant to any program that takes input from stdin. For cases where I know that colleagues have needed this with Gromacs, we've used the first option listed below (heredoc). FWIW, I didn't test either of these with Gromacs, but they should work.

1. Heredoc

A very common way to make an interactive program into a script is by using heredoc format. This allows you to write a shell script that acts as if it was receiving the input within the heredoc. In particular, people use heredoc for exactly this purpose with Gromacs. This is particularly useful if you're using this as one step among several in a workflow, and you'd like the whole workflow to be in a script.

You use heredoc within another scripting language. Most shell scripting languages support it. With sh, you should be able to write a script that looks something like this:


# This is in the file heredoc.sh

gmx make_ndx -f em.gro -o index.ndx << EOF
1 | 13

# don't forget the line with q to quit and save!

Then you run that script as sh heredoc.sh. Here I chose the text EOF as a marker, but that is up to you -- any text is allowed, but it must bracket the start and end of the input section. Here's some more documentation on heredocs.

This is a generic shell scripting technique; not at all specific to Gromacs. I can write a little Python program that takes the same inputs as a sort of "pretend" gmx make_ndx:

# myscript.py
indices = input()
quit = input()
assert quit == "q"
print('indices = ', indices)

and a heredoc based shell script:

python myscript.py << EOF
1 | 13

And then:

$ sh heredoc.sh
indices =  1 | 13

2. Keep the inputs in a separate file (input redirection)

You can also keep a separate file with the inputs. In the file inputs.txt:

1 | 13

Then gmx make_ndx -f em.gro -o index.ndx < inputs.txt should work. Using my python script above:

$ python myscript.py < inputs.txt
indices =  1 | 13

When to use each

Use heredoc if this is part of a bigger script, or if the input data is closely associated with the program (only to be used once). Use input redirection if the input is distinct from the program or likely to be reused. In your use case, I would usually use heredoc.

  • $\begingroup$ +1. Don't forget to upvote the question if it was worthy enough to answer! $\endgroup$ Commented Dec 28, 2021 at 8:21

How about this, also writes to a log file. This selects both group 1 and group 13 and write the indices to a index file (index.ndx)

echo -e "1|13\nq"| gmx make_ndx -f em.gro -o index.ndx|& tee -a youlogfile.log
  • $\begingroup$ I tested. This doesn't work. $\endgroup$ Commented Dec 28, 2021 at 11:22
  • 1
    $\begingroup$ @scamander My bad I overlooked the OP. I updated my answer, Have a look $\endgroup$
    – Vasista
    Commented Dec 28, 2021 at 12:55
  • $\begingroup$ should we use | instead of &? That is "1|13\nq" $\endgroup$ Commented Dec 28, 2021 at 13:16
  • 2
    $\begingroup$ I just use echo "1" "13" | the-command. $\endgroup$
    – Camps
    Commented Dec 28, 2021 at 16:29
  • 1
    $\begingroup$ @NikeDattani I modified @Vasista OP echo -e "1|13\nq"| gmx make_ndx -f em.gro -o index.ndx then it works. $\endgroup$ Commented Dec 29, 2021 at 13:21

Just to give you another option if you want to keep using pipe and echo. I have been doing it with the following syntax:

echo "1 13" | gmx...

This had been working for me, but I like the answer currently.

  • 1
    $\begingroup$ +1. Great first answer, and welcome to our new community! We hope to see much more of you in the future!!! $\endgroup$ Commented Mar 22, 2022 at 18:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .