I have a script I execute in the background and capture all output with a command like this:

nohup bash -x test.sh < /dev/null > log.txt 2>&1 &

How can I find out how long it took to complete? If I try to use time after bash -x I get an error:

/usr/bin/time: /usr/bin/time: cannot execute binary file

If I try to use acct it doesn't seem to log the process or I can't find it.

  • time before or after bash? Mar 18 '20 at 10:21

Just time the nohup process:

$ time nohup bash -x ~/scripts/foo.sh 
nohup: ignoring input and appending output to 'nohup.out'

real    0m10.011s
user    0m0.005s
sys 0m0.006s

foo.sh simply has sleep 10 as an example.


[this assumes that you want the output of time to also go to log.txt, something which is not clear from your question]

Just don't use nohup.

nohup does nothing special but ignoring the SIGHUP signal, redirecting stdout and stderr to a file and --only in some variants, like the nohup from GNU coreutils-- redirecting the stdin from /dev/null opened in write-only mode.

You can easily do all that from the shell:

{ trap '' HUP; time bash -x your_script args ... ; } > log.txt 2>&1 0>/dev/null &

Or safer, if started from a script or if you don't plan to ever bring back the command to the foreground with fg:

(trap '' HUP; time bash -x your_script args ... 0>/dev/null &) > log.txt 2>&1

(You can omit the 0>/dev/null if you don't care to emulate that feature of GNU nohup).

Of course, you can use the syntax trick from the first example with nohup too if, for some unfathomable reason, you ascribe magical properties to nohup:

{ time nohup bash -x your_script args ... ; } > log.txt 2>&1 &
  • Thanks. Really good answer...but what if your script takes arguments? Like a path ? Your safer approach breaks my script and I don't know why. It's a ffmpeg script that process some files in a folder
    – Freedo
    Mar 19 '20 at 7:50
  • You add the arguments after your_script arg1 arg2, your_script "$@", etc. How does your ffmpeg script break?
    – mosvy
    Mar 19 '20 at 7:55
  • @Freedo maybe ffmpeg tries to open the controlling terminal for one reason or another -- try using its -nostdin option, or run it via setsid ffmpeg ...
    – mosvy
    Mar 19 '20 at 8:10
  • nevermind it's working now. It was an unrelated issue. Thanks
    – Freedo
    Mar 19 '20 at 8:33

You could just use:

time yourscript.sh

But if that doesn't work for you, you can wrap your content of script like:

STARTTIME=$(date +%s)
#command block that takes time to complete...
ENDTIME=$(date +%s)
echo "It takes $($ENDTIME - $STARTTIME) seconds to complete this task..."
  • We are talking about hours, even days here but thanks. I like your approach
    – Freedo
    Mar 18 '20 at 9:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.