To make sure that your application is disassociated from its terminal - so that it will not interfere with foreground commands and will continue to run after you logout - nohup
ensures that neither stdin nor stdout nor stderr are a terminal-like device. The documentation describes what actions it takes:
If the standard output is a terminal, all output written by the named
utility to its standard output shall be appended to the end of the file
nohup.out in the current directory. If nohup.out cannot be created or
opened for appending, the output shall be appended to the end of the file
nohup.out in the directory specified by the HOME environment variable. If
neither file can be created or opened for appending, utility shall not be
invoked.
If the standard error is a terminal, all output written by the named
utility to its standard error shall be redirected to the same file
descriptor as the standard output.
You redirected stdout to a file when you typed > exhibitor.out
in your command line. If you're OK with having your application's stderr be directed to the same file as its stdout, you don't need to do anything else. Or you can redirect stderr to a different file by adding an argument such as 2> exhibitor.err
. (Thanks to an unknown user - my notifications didn't show a name - for suggesting inclusion of this alternative.)
With zsh
(and zsh
only) and its multios
feature:
your-cmd 2> stdout+stderr.log >&2 2> stderr.log
As fd 2 is redirected twice, zsh
implements an internal tee
to have it sent to both files.
With bash
(or any Bourne-like shell (other than zsh
where you'd need to disable multios
for it to work here)), you can do the tee
ing by hand with:
{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
(though you lose the exit status of your-cmd
. zsh
has it in $pipestatus[1]
, bash
in "${PIPESTATUS[0]}"
though (provided the redirection into stderr+stdout.log
didn't fail)).
To record the pid of your-cmd
, you could do:
{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- |
tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
With yash
and it's process redirection feature:
your-cmd > stdout+stderr.log 2>(tee stderr.log)
(but note that yash
will not wait for the termination of that tee
command, so the log files may not be complete by the time you run the next command after that).
Something similar (and with the same caveat) can be done with process substitution in bash
, zsh
and ksh93
:
{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log
To run in background and get the pid:
(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!
With rc
:
{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log
rc
's pipes allow specifying which file descriptors are connected to the pipe. With other shells, it's always fd 1 of the left command and fd 0 of the right one (hence the little dance with fd 3 above to shift file descriptors around). rc
will report failure if either your-cmd
or tee
fails, though the exact number may be lost.
Best Answer
Yes, exactly that can happen if lines to
stdout
are long enough.Running:
Checking: Open file
out
in an editor and find stderr!
in between-
, not always betweenEND
andSTART
This will vary between OS:s, languages and systems in various ways, but your basic assumption is correct. Experiment by varying length of stdout-lines:
print "-" x 100
,print "-" x 10000
etc.