Advanced

How to close the terminal without killing the running program

Posted by annamese on · 11 comments
Linux and Life
Mail this story
Print this story

Normally when you use the terminal to launch a program, if you want to close the terminal, you will have to close the running program as well. This trick is about how to close the terminal without killing the running program.

Full Story

  Nav
» Read more about: Story Type: Tutorial

» Get new stories by e-mail: nightly or as they are published

« Return to the newswire homepage

  Related stories
» More like this

Comments (11)

It seems to me that once upon a time, I was able to do something like this just by backgrounding the task

eg:
 $ "xload & "  
(My memory is admittedly rather vague and untrustworthy on this particular detail)

However, for quite some while I have found that this works for some things, but not for others:

 $ "xterm & "  
produces an xterm that will stay around when I close the originating gnome-terminal

while
 $ "xload & "  
gives me an xload that goes away when the originating terminal does

but if I put
 $ "xload & "  
or these days,
 $ "gkrellm & "  
into a script, and run that script from a terminal, I can then safely close the terminal without losing the xload or gkrellm instance.

(And launching xload or gkrellm from the Alt-F2 run command dialouge also works)

Does anybody have a good link for an explanation of this matter?

(PS: "disown" appears to be a bash-builtin)
without verifying, i believe it works like this: when the terminal closes, the program inside receives a signal, that it can either catch and react to or not.

greetings, eMBee. (removed incorrect and unclear statements)
It's a matter of catching forwarded signals.

When you close gnome-terminal, its shell's child processes get SIGTERM's. Just like when you press Ctrl-C, the shell sends a SIGINT to the foreground child process.

"xeyes" doesn't ignore SIGTERM; "xterm" and "gkrellm" do. That's why "xeyes &" will go away when you close gnome-terminal, but "xterm &" and "gkrellm &" continue running.

But, if you "disown %N", then that job is removed from the shell's list of child processes, so the shell is no longer concerned with sending them signals. That's a function of the shell.

Clear as mud?
Sorry Gus3,

I see my post somehow dropped a piece when I posted it (yeah that's it, it was the post that screwed up -- it couldn't have been me)

I've edited the original post to insert that line.

But yes, I followed your explanation.

It matches this bit from the bash-builtins man page
 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  sup-
              plied,  the  shell's  notion of the current job is used.  If the -h
              option is given, each jobspec is not removed from the table, 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 sup-
              plied, 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 jobspec does  not  specify  a
              valid job.


But I was looking for a little more, and a little less dryly technical. For example, is xterm compiled to ignore SIGHUP?
According to /proc/(pid)/status on my machine, xterm ignores SIGHUP (signal 1) and SIGTTOU (signal 22). I see no patches in my source repo, so I assume that means it's that way by design.

EDIT: Look for the line starting with "SigIgn". The hex bits that are set are the ignored signals, but the LSB is bit 1, not bit 0.
I would never have thought of looking in /proc for anything like that
And screen, of course :)
nohup uses the same principle as xterm and gkrellm: ignore the signal (SIGHUP here), then exec(). You can see the pertinent kernel call with the following command:
strace nohup cat /dev/null
Then scroll back and look for the line beginning with "rt_sigaction". That's the "ignore SIGHUP" call. Immediately following are a few calls to "execve", searching for "cat" in the $PATH.

screen is a horse of a different hex triplet.
Cool!

I remembered nohup, but mis-remembered it as a GNU option ( --no-hup ), or perhaps that's just for particular commands.

And I presume that "insulating" a command in a script works because as far as Bash shell is concerned, the script completed (returned a "command succeeded" signal)?
Not sure what you mean by "insulation," but the background invocation (with the ampersand) succeeds if the command is found and executed. If it isn't found, or can't be executed (say, with -rw-rw-rw- permissions), it returns a non-zero status. In either case, execution continues in the command stream.

If a background job returns to the foreground, through "fg" or with the "%N" (percent-N) notation, its exit status will be reflected normally in $?.

If you have several jobs in the background, and you "wait" for them, essentially putting them all in the foreground at once, the command's exit status is success. If you "wait %N1 %N2 %N3" for them, the wait command's exit status is the status of %N3. That is, if I'm reading correctly the man page for bash.

Post a comment

A free account is needed to post. Write your comment here first: your text is kept in this browser while you sign up or log in, and is waiting for you when you come back.

Your message:
|||||
10
Markdown: **bold**, *italic*, [text](https://link), - lists, > quotes, $x^2$ for math. Formatting help

Sign up and post (it is free)  or  Log in and post