Harm Doedens
Harm Doedens

Reputation: 35

nohup bash call with sleep is evaluated incorrectly

I am trying do execute a script, detached, with a delay and in the background.

I have the following script:

#!/bin/sh
echo "[$(date)][${HOST}] Immediate date" > ~/out.log
nohup bash -c "sleep 2 && echo '[$(date)][${HOST}] Delayed date'" >> ~/out.log 2>&1 &

I expect that out.log would contain exactly two lines like so:

[Tue Apr  4 08:55:56 CEST 2017][] Immediate date
[Tue Apr  4 08:55:58 CEST 2017][] Delayed date

Note the timestamps being 2 seconds apart. But instead bot dates read exactly the same time...

[Tue Apr  4 08:55:56 CEST 2017][] Immediate date
[Tue Apr  4 08:55:56 CEST 2017][] Delayed date

When I try it without the nohup and bash -c the output is as expected, but the calling script would have to keep running, otherwise the second command will be aborted.

What causes the date not being different and to fix it?

edit:

I had simplified the command for stackoverflow. But now when I expand it again I run into another variable expansion problem. When I add the HOST variable:

HOST=foo.bar
nohup bash -c 'sleep 2 && echo "[$(date)][${HOST}]" Delayed date' >> ~/out.log 2>&1 &

the output file dos not contain foo.bar:

[Tue Apr  4 12:52:11 CEST 2017][]

Upvotes: 2

Views: 3365

Answers (2)

W.Mann
W.Mann

Reputation: 923

The $(date) is evaluated by the outside shell script. If you swap the " with the ', it works as you expect it to work. This is because $(..) in double quotes is resolved, even if you put it in single quotes inside the double quoted string.

#!/bin/sh
echo "[$(date)][${HOST}] Immediate date" > ~/out.log
nohup bash -c 'sleep 2 && echo "[$(date)]['"${HOST}"'] Delayed date"' >> ~/out.log 2>&1 &

Edit: Make the code work w.r.t. $HOST + $HOST containing whitespace

Upvotes: 2

Darren
Darren

Reputation: 53

I believe that double quotes in the nohup will evaluate the expression in the nohup command immediately. Changing your double quotes into single quotes (and using the double quotes for the echo may help, e.g

#!/bin/sh
echo "[$(date)][${HOST}] Immediate date" > ~/out.log
nohup bash -c 'sleep 2 && echo "[$(date)][${HOST}] Delayed date"' >> ~/out.log 2>&1 &

Upvotes: 0

Related Questions