I have a script called by cron to run an LSF job.
I would like to be told when that job is submitted and when it completes. The-Powers-That-Be have decided to disable email notifications. So I am writing this script to output the relevant information to a logfile.
It almost works. Here is some code:
crontab:
00 12 * * * my_script.sh my_job.bsub
my_job.bsub:
#!/bin/bash
#BSUB -q my_queue
#BSUB -W 06:00
echo "I am a long process"
sleep 60
my_script.sh:
#!/bin/sh
BSUB_SCRIPT=$1
# run bsub_script (and get the LSF job id while you're at it)...
JOB_ID=`bsub < $BSUB_SCRIPT | awk -F[\<,\>] '{print $2}'`
# log that job was submitted...
echo "`date +%Y-%m%d %T` submitted '$BSUB_SCRIPT' [$JOB_ID]" >> $HOME/my_logfile.txt
# and log when job completes...
bsub -w "ended($JOB_ID)" << EOF
#!/bin/bash
#BSUB -q my_queue
#BSUB -W 00:30
echo "`date +%Y-%m-%d %T` completed '$BSUB_SCRIPT' [$JOB_ID]" >> $HOME/my_logfile.txt
EOF
(I found this answer helpful in figuring out how to submit a job that waits until an earlier one has completed.)
The issue is that the 2nd call to date
, in the heredoc, gets evaluated immediately, so I wind up with a logfile that looks like this:
my_logfile.txt:
2018-01-30 13:15:14 submitted 'my_job.bsub' [1234567]
2018-01-30 13:15:14 completed 'my_job.bsub' [1234567]
Notice how the times are exactly the same.
How can I ensure that evaluation of the content of the heredoc is deferred until the LSF job runs?
The date
command in the heredoc is being expanded before being passed to bsub
. You need to quote the EOF
in your heredoc expression or escape the date
command. See the answer to this question:
How does "cat << EOF" work in bash?
In particular:
The format of here-documents is:
<<[-]word here-document delimiter
...
If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion.
So, for example when I run
$ cat << EOF
> echo `date`
> EOF
The output is
echo Tue Jan 30 11:57:32 EST 2018
Note that the date
command is expanded, which is what's happening in your script. However, if I quote the delimiter in the heredoc:
$ cat << "EOF"
> echo `date`
> EOF
You get the unexpanded output you want:
echo `date`
Similarly, escaping date would preserve the other variables you want to expand:
$ cat << EOF
> echo \$(date)
> EOF
Output:
echo $(date)