How can I send specific messages to stdout from a bash prompt with multiple commands that is run via nohup?

39 views Asked by At

I want to run multiple commands that are concatenated via && with nohup. The output of the commands are redirected to nohup.out which is fine. But I want send some messages in between to stdout. Is that possible?

A simple example would be like:

nohup sh -c " \
echo some message 1 (to stdout) && \
some command 1 (to nohup.out) && \
echo some message 2 (to stdout) && \
some command 2 (to nohup.out) && \
..." &

I tried to to redirect the messages to stderr within the commands and then redirect stderr back to stdout:

nohup sh -c " \
echo some message 1 >&2 && \
some command 1 (to nohup.out) && \
echo some message 2 >$2 && \
some command 2 (to nohup.out) && \
..." 2>&1 &

But this did not work for me.

Any suggestions?

1

There are 1 answers

0
tripleee On

By definition, nohup redirects any output to nohup.out.

A simple workaround is to write somewhere else, and maybe have your shell display the contents of "somewhere else".

touch "$HOME"/.nohuplog
tail -f "$HOME"/.nohuplog &
nohup sh -c '
    exec 3>>"$HOME"/.nohuplog
    set -e # to avoid repeated "&&"
    echo "some message 1" >&3
    some command 1 (to nohup.out)
    echo "some message 2" >&3
    some command 2 (to nohup.out)
    ...' &

The exec 3>... so that you can use >&3 and don't have to repeat >>"$HOME"/.nohuplog is just to make the code less repetitive.

You could use a FIFO instead of a file, or etc.

Maybe for improved usability add a trap to explain why the script exited in the case of an error. Bash offers the ERR pseudo-signal for trap for this purpose.

Alternatively, if you redirect standard output and/or standard error, no output will end up in nohup.out; this is frequently a better solution.

nohup sh -c '
    exec >>"$HOME"/.nohuplog
    exec 2>>"$HOME"/.nohuperr
    set -e # to avoid repeated "&&"
    echo "some message 1" >&2
    some command 1 (to nohup.out)
    echo "some message 2" >&2
    some command 2 (to nohup.out)
    ...' &
tail -f "$HOME"/.nohuplog "$HOME"/.nohuperr &

(Probably use a less generic file name for the destination files, too.)