frankscup
frankscup

Reputation: 71

Redirecting stdout & stderr from background process

I have a script called foo that runs the program a.exe and sends the timing statistics to a file, time.log

#!/bin/bash
date 1>> time.log
(time ./a.exe) 2>> time.log

This works if I run the script in the background of my terminal and keep my shell open until a.exe finishes, but if I run the script in the background and exit my terminal (a.exe takes a long time to run)

foo & 
exit

when I come back, a.exe has executed but the time statistics do not appear in my log file. Does anyone know why this is? Is there a way to get the timing statistics after I've closed the parent shell?

thanks

Upvotes: 7

Views: 13039

Answers (5)

khachik
khachik

Reputation: 28703

Try:

nohup <your_command> &

Upvotes: 0

harithski
harithski

Reputation: 686

Your a.exe gets killed when you close the parent shell.

You could type screen, run the command as usual and exit the screen. This keeps the process from getting killed when the parent shell is exits. This method is a little cumbersome but might be handy in other situations.

John gave a much better answer - use nohup.

Upvotes: 0

dennycrane
dennycrane

Reputation: 2331

Since the question is tagged as bash as well, I quote from man bash

disown [-ar] [-h] [jobspec ...]
          Without  options,  each  jobspec  is  removed  from the table of
          active jobs.  If jobspec is not present, and neither -a  nor  -r
          is  supplied, the shell's notion of the current job is used.  If
          the -h option is given, each jobspec is not removed from the ta‐
          ble,  but is marked so that SIGHUP is not sent to the job if the
          shell receives a SIGHUP.  If no jobspec is present, and  neither
          the  -a  nor the -r option is supplied, the current job is used.
          If no jobspec is supplied, the -a option means to remove or mark
          all  jobs;  the  -r  option without a jobspec argument restricts
          operation to running jobs.  The return value is 0 unless a  job‐
          spec does not specify a valid job.

This comes in handy when you started a job but forgot to prefix it with nohup. Just do

disown -ah
disown -a

Upvotes: 2

Rahly
Rahly

Reputation: 1511

Don't forget to remove all references to the tty/pts, 0</dev/null removes the stdin reference.

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 362037

nohup foo &

When you exit your shell it sends a SIGHUP signal to all child processes, which by default kills them. If you want a process to continue executing even when the parent shell exits then you need to have it ignore the SIGHUP.

NAME

nohup -- invoke a command immune to hangups

SYNOPSIS

nohup utility [arg ...]

DESCRIPTION

The nohup utility invokes command with its arguments and at this time sets the signal SIGHUP to be ignored. If the standard output is a terminal, the standard output is appended to the file nohup.out in the current directory. If standard error is a terminal, it is directed to the same place as the standard output.

Upvotes: 7

Related Questions