Home > other >  nohup append the executed command at the top of the output file
nohup append the executed command at the top of the output file

Time:09-18

Let's say that we invoke the nohup in the following way:

nohup foo.py -n 20 2>&1 &

This will write the output to the nohup.out. How could we achieve to have the whole command nohup foo.py -n 20 2>&1 & sitting at the top of the nohup.out (or any other specified output file) after which the regular output of the executed command will be written to that file?

The reason for this is for purely debugging purpose as there will be thousands of commands like this executed and very often some of them will crash due to various reasons. It's like a basic report kept in a file with the executed command written at the top followed by the output of the executed command.

CodePudding user response:

A straightforward alternative would be something like:

myNohup() {
  (
    set  m                         # disable job control
    [[ -t 0 ]] && exec </dev/null  # redirect stdin away from tty
    [[ -t 1 ]] && exec >nohup.out  # redirect stdout away from tty
    [[ -t 2 ]] && exec 2>&1        # redirect stderr away from tty
    set -x                         # enable trace logging of all commands run
    "$@"                           # run our arguments as a command
  ) & disown -h "$!"               # do not forward any HUP signal to the child process
}

To define a command we can test this with:

waitAndWrite() { sleep 5; echo "finished"; }

...and run:

myNohup waitAndWrite

...will return immediately and, after five seconds, leave the following in nohup.out:

  waitAndWrite
  sleep 5
  echo finished
finished

If you only want to write the exact command run without the side effects of xtrace, replace the set -x with (assuming bash 5.0 or newer) printf '%s\n' "${*@Q}".

For older versions of bash, you might instead consider printf '%q ' "$@"; printf '\n'.


This does differ a little from what the question proposes:

  • Redirections and other shell directives are not logged by set -x. When you run nohup foo 2>&1 &, the 2>&1 is not passed as an argument to nohup; instead, it's something the shell does before nohup is started. Similarly, the & is not an argument but an instruction to the shell not to wait() for the subprocess to finish before going on to future commands.
  • Related