Search code examples
bashstdoutstderr

How to print everything that is printed and can be seen on terminal


I want to print all the output from GROMACS 5.1.2.

I know how to use > and < for std in and out, also tried 2>&1 to print error and output together, tried separately too, it will still not print everything, especially some useful hints in the end when it tells me what was the problem and I need that information.

I think this will not be saved because it is coming from a different code, the main program executes a sub program, and that crashes, and I get the report only on screen. I will have in the output that something went wrong, and what that something is, but on the screen I have much more information.

If anyone has any idea how I could do that, I would really appreciate it.

Also I'm not complete noob, but if you can be explicit in your explanation, that is greatly appreciated.

For example if you would like to try gmx pdb2gmx command with the 3mlj.pdb from RCBS Protein Database, on screen I will be reading:

Fatal error:
Residue 'CU' not found in residue topology database

But in the standard output I will only read:

This chain does not appear to contain a recognized chain molecule.

For me that CU is really important information, and this is just an example.

I'm sharing my operating system here:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.4 LTS
Release:    14.04
Codename:   trusty

Also tried on this with the exact same result:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 15.10
Release:    15.10
Codename:   wily

My bash script that I want to run for batch files:

#$ -S /bin/bash
for infile in *.pdb
do
    gmx pdb2gmx -f $infile -o ${infile/pdb/gro} -water spce -ff oplsaa \
        -p ${infile/pdb/top} -i ${infile/pdb/itp} 2>&1 > ${infile/pdb/err}
done

Solution

  • You must do I/O redirections in the correct order (left to right).

    You have:

    gmx pdb2gmx …  -i ${infile/pdb/itp} 2>&1 > ${infile/pdb/err}
    

    This sends standard error to where standard output is currently going (the terminal), and then sends standard output (but not standard error) to a file.

    You need:

    gmx pdb2gmx …  -i ${infile/pdb/itp} > ${infile/pdb/err} 2>&1
    

    This sends standard output to a file, and then sends standard error to the same place. Note that in both systems, there are still two separate file descriptors (1 or standard output, and 2 or standard error) in use; the only question is which file the file descriptor is connected to.

    If you're piping data, the pipe is set up before other I/O redirections are dealt with, but otherwise, I/O redirections per command are processed left-to-right.

    See also How to pipe stderr and not stdout, and Bash I/O Redirections.