5

I want to spawn a process and run it at the top level so that when the shell exits, the process keeps running.

I had mistakenly thought that nohup would do this, but when I exit from the shell (the shell is a lxc container and I ssh into that) and re-enter, the process is gone.

It seems (looking at pstree) that the process is still under the invoking shell even with nohup or disown.

I tried a few options and setsid seems to work - but am I doing something wrong with nohup here ?

$ cat myproc
sleep 1234

$ myproc &
$ pstree -a | grep -B 3 "1234" | grep -v grep
  |-screen 
  |   |-bash -ls
  |   |   |-bash -ls
  |   |   |   `-sleep 1234


$ nohup myproc &
$ pstree 
  |-screen 
  |   |-bash -ls
  |   |   |-pstree -a
  |   |   `-sh ./myproc
  |   |       `-sleep 1234

$ myproc &
$ disown $!
$ pstree -a | grep -B 3 "1234" | grep -v grep
  |-screen 
  |   |-bash -ls
  |   |   |-bash -ls
  |   |   |   `-sleep 1234

$ setsid myproc &
  |-sh ./myproc
  |   `-sleep 1234

success. But why did nohup not achieve the same? Is there a way to use nohup more correctly?

3

It's a little hard to diagnose, as you don't give source for myproc, but I suspect that your problem has something to do with "controlling TTY". I wrote a small shell script that just calls sleep 100. I ran it under nohup:

$ nohup ./sleeper > sleeper.out &

[1] 25305
-bash-3.2$ jobs
[1]+  Running                 nohup ./sleeper > sleeper.out &
-bash-3.2$ ps -l -p 25305
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S 429624 25305 18252  0 77   0 - 15961 wait   pts/0    00:00:00 sleeper

If you look at the ps output, you see a column named "TTY". At least some versions of nohup (the one I used above is from GNU coreutils, version 5.97, so relatively old). When I exited the bash shell from which I started sleeper, the TTY column changed to '?', meaning that sleeper didn't have one.

If myproc doesn't deliberately detach itself from it's controlling TTY, it's still possible to get things like a SIGPIPE signal if it tries to write to stdout. It seems to me other things are possible, but I can't recall or google anything up.

If you can find or compile "daemonize", you might want to try it. If myproc is compiled, you could modify the source to call the daemon(3) library function.

  • I'm starting to think the issue is with the process being spawned (which we do not own) as spawning "sleep 1234" which is what I was doing above in lieu of the real process, works fine with lxc containers and detaches ok. It was only with this specific process. So it could be that some other signal is causing that program to exit (it was called during 'init' via nohup) and using setsid avoid the program exiting. Lot of conjecture I know. Thanks for the help anyway. – Neil McGill Sep 17 '14 at 22:02
1

You can use at for this.

The at utility shall read commands from standard input and group them together as an at-job, to be executed at a later time.

The at-job shall be executed in a separate invocation of the shell, running in a separate process group with no controlling terminal, except that the environment variables, current working directory, file creation mask, and other implementation-defined execution-time attributes in effect when the at utility is executed shall be retained and used when the at-job is executed.

echo myproc | at now

...will work, though on some systems you need to configure that at daemon monitor first.

1

To completely detach a process:

nohup ./command &

stdout & stderr will be written to a file named nohup.out located in the same directory where nohup has been executed.

If you wish to execute a detached command while being able to see the output in the terminal, then use tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./command &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

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.