2

I am trying to run a background-job that should send an email after it terminates. The background-job can run several hours and should run independent of the Shell it was started in (because SSH will disconnect). In my current script below the mail command does not wait for the BACKGROUNDJOB to terminate. How can I achieve this?

nohup BACKGROUNDJOB -l $corefolder/$filename >/dev/nul 2> $corefolder/$filenameerr &
mail -s "JOB DONE" -A $corefolder/$filename -A $corefolder/$filenameerr abc123@gmail.com <<< "job finished on $HOSTENAME on $(date)"

The mail should attach 2 output files from the BACKGROUNDJOB, which are only available after it has terminated.

Or generally:
#Script.sh
Process 1 (e.g. run rsync) [this could take 10h and only then rsync.log is available]
Process 2 (send email with rsync.log as attachment)
#end script

AND the entire script should put itself in the background to run independent of the shell and continue running even when ssh disconnects.

Marc
  • 305
  • Write a simple bash script to invoke your BACKGROUND JOB, wait (see man $SHELL about "Job Control"), then send the mail. nohup that script. – waltinator Mar 21 '23 at 05:13
  • thats what my script above is showing but the mail is sent before the first part ends. – Marc Mar 21 '23 at 06:26
  • Don't put BACKGROUND_JOB in the background (remove trailing &) and nohup the_script &. Put the whole script in the background as a simgle blob – waltinator Mar 21 '23 at 06:40
  • Calling the script as "nohup script.sh" is not ideal as the script will be used by others who should just be able to execute as "script.sh" (without having to consider whats happening in the foreground/background etc). There must be a way to execute wihtin a script 2 processes in the background while 2nd is dependent on the 1st and is waiting in the background. – Marc Mar 21 '23 at 08:05
  • @Marc you could have an optional argument in the script that, if set, causes the mail to be sent. – muru Mar 21 '23 at 08:13

1 Answers1

4

... and should run independent of the Shell it was started in

It can't run independent of the Shell it was started in ... It needs the shell to interpret its commands all the way through until its end/exit.

(because SSH will disconnect)

Disconnecting SSH will result in disconnecting the user's terminal which will in turn result in a SIGHUP(hang-up) signal and the latter will cause the shell to terminate as the shell is merely a child process of the parent user's terminal ... In bash, you can tell your shell to ignore the SIGHUB signal with the job control builtin disown

In my current script below the mail command does not wait for the BACKGROUNDJOB to terminate. How can I achieve this?

If you nest the commands in order e.g. comman1; command2; ... without sending any preceding commands to the background like e.g. so:

BACKGROUNDJOB -l $corefolder/$filename >/dev/nul 2> $corefolder/$filenameerr; mail -s "JOB DONE" -A $corefolder/$filename -A $corefolder/$filenameerr abc123@gmail.com <<< "job finished on $HOSTENAME on $(date)"

Then the latter command will wait for the former command to complete execution first.

the entire script should put itself in the background to run independent of the "shell"(you mean parent terminal) and continue running even when ssh disconnects.

You can achieve this like so (the sub-shell syntax (...) might not be always needed here but doesn't harm to use in all cases):

(/path/to/scriptfile) & disown

Or if you like to nest the commands in order instead, like so (the sub-shell syntax (...) is needed here):

(BACKGROUNDJOB -l $corefolder/$filename >/dev/nul 2> $corefolder/$filenameerr; mail -s "JOB DONE" -A $corefolder/$filename -A $corefolder/$filenameerr abc123@gmail.com <<< "job finished on $HOSTENAME on $(date)") & disown
Raffa
  • 32,237
  • 1
    Raffa. Awesome. Your last line is the solution to my problem. Many thanks for this one-liner!!! – Marc Mar 21 '23 at 10:26