I'm learning Linux. Came upon the idea that a process can be attached to a terminal. What does it mean to attach a process to a terminal (TTY) and why would I want to do it?
-
I think you need to clarify what you mean with a process attached to a terminal, please edit your question. – dessert Sep 16 '17 at 07:32
-
2@dessert I think that's what the question is about. "What does that mean?" – Kusalananda Sep 16 '17 at 07:47
-
2Related: https://unix.stackexchange.com/questions/4126/what-is-the-exact-difference-between-a-terminal-a-shell-a-tty-and-a-con – Kusalananda Sep 16 '17 at 07:48
-
1Related: How to recover a backgrounded job from a previous shell?, How can I disown a running process and associate it to a new screen shell?, attach to tty running a process, any way to un-disown / re-attach an interactive process to the tty?, Run server program and allow user to attach to it using SSH, and probably more. This seems like an answerable question. – G-Man Says 'Reinstate Monica' Aug 09 '18 at 02:44
1 Answers
NOTE: For a good primer on job control in Unix I'd direct you to the Wikipedia page on the topic - Job control (Unix).
Attached terminal?
The phrase, "attached to terminal", is typically what you'll hear when talking about jobs in a shell context. But it does have other meanings. the phrase "attach a process to a terminal" can also mean using a tool such as gdb
or strace
or lsof
to attach to a specific process ID (PID) and list information or monitor it.
I'll discuss both, but to start, I'm going to cover job queues, since I suspect that's the one you're looking for.
Background - job queues
In Unix like operating systems, you'll typically see the concept of jobs. In most Unix like operating systems that I've used they all generally work in a similar fashion. That is, they can be backgrounded and assigned a number in a queue (job queue), and they can be acted on from the context of their number in this job queue.
To put something into the job queue, they typically call this act, backgrounding. When you resume a job that's been backgrounded, you call this foregrounding. The commands to do this are bg
and fg
typically. You can also put jobs into the background immediately using the ampersand &
at the end of any command you run.
Examples
jobs
$ sleep 2 &
[1] 19189
Here I'm running a sleep command for 2 seconds and backgrounding it. The output immediately gives you useful info, such as the job queue number ([1]
) and the process ID of the backgrounded job, 19189.
When this job eventually terminates it'll print this type of message in the terminal from where it ran:
$
[1]+ Done sleep 2
foreground & background
To act on jobs that have been backgrounded:
$ sleep 20 &
[1] 19207
$ fg
sleep 20
^C
Here I've sent a job to the background (&
), then brought it back to the foreground (fg
) and then killed it with the Ctrl+C (^C
) command.
If we had multiple backgrounded jobs:
$ sleep 20 &
[1] 19224
$ sleep 20 &
[2] 19225
$ sleep 20 &
[3] 19226
$ jobs
[1] Running sleep 20 &
[2]- Running sleep 20 &
[3]+ Running sleep 20 &
We can see them with the jobs
command. Notice the little +
and -
next to #3 and #2. If I run the fg
command without specifying a job queue number, I'll get the last job that was put into the job queue (+
). For example:
$ fg
sleep 20
^C
$ jobs
[1]- Running sleep 20 &
[2]+ Running sleep 20 &
killing
You can use the job queue numbers to act on the jobs. One such method is to kill them. To refer to a job queue's number, you prefix them with a %
when you want to refer to them with other commands, such as kill
. You can of course kill
multiple all at once, or just one:
$ kill %3 %4 %5
$ jobs
[3] Terminated sleep 20
[4] Terminated sleep 20
[5]- Terminated sleep 20
[6]+ Running sleep 20 &
Background attaching to a PID
To attach a process to a terminal could also mean the following. Here's my shell's PID:
$ echo $$
23543
In another shell I'm running strace
and connecting to this process to see what system calls it's making:
$ strace -p 23543
strace: Process 23543 attached
read(0,
NOTE: Here you can see that it's waiting in a read
for commands. That's what terminals/shells do.
Here we can see that I've started to type the command ls
within it, and the shell is echoing this backout to the shell in the form of write()
system calls.
read(0, "l", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "l", 1) = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "s", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "s", 1) = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0,
This is another form of attaching a process to a terminal.
Other forms
One of the more obscure references to attaching a process to a terminal could be assumed here as well. This U&L Q&A titled: How to attach terminal to detached process? covers that one in all its forms.
The basic premise with this form of the reference, is that you've taken a backgrounded job, and "disconnected" it from the current shell. You do this using the commands nohup
or disown
.
Once a process has been disowned, you can no longer use the jobs
, fg
or bg
commands to act on it. It's no longer associated to your current shell's PID.
The traditional method for re-acquiring a previously disowned process is to use a tool such as reptyr
, which will re-attach a PID to your existing shell. For example say we start 2 jobs and nohup
them:
$ nohup sleep 200 &
[1] 19720
$ nohup sleep 200 &
[2] 19721
Still attached to our terminal's job queue, let's disown
them:
$ jobs
[1]- Running nohup sleep 200 &
[2]+ Running nohup sleep 200 &
$ disown -a
Now they're gone:
$ jobs
$
They're still listed as being children of our original shell's PID (23543):
$ ps -eaf|grep -E "19720|19721"
vagrant 19720 23543 0 18:29 pts/1 00:00:00 sleep 200
vagrant 19721 23543 0 18:29 pts/1 00:00:00 sleep 200
Now if we exit and log back in, we'll see that these processes are now listed as being parents of the main PID, 1:
$ ps -eaf|grep -E "19720|19721"
vagrant 19720 1 0 18:29 ? 00:00:00 sleep 200
vagrant 19721 1 0 18:29 ? 00:00:00 sleep 200
These processes were able to do this because we nohup
ed them and disown
'ed them. Let's reattach one of them:
$ reptyr -s 19720
[-] Timed out waiting for child stop.
^C
NOTE: In the above, I've reattached PID 19720 to my shell and then killed it via Ctrl+C. We can see it's gone now:
$ ps -eaf|grep -E "19720|19721"
vagrant 19721 1 0 18:29 ? 00:00:00 sleep 200

- 369,824
-
If someone edits the answer later, remember to change "parents of the main PID" to "children of the main PID". You need 10 char minimum to accomplish an edit (not 8). – Jose_X May 15 '21 at 10:08