How do I attach a terminal to a detached process?

I have detached a process from my terminal, like this:

$ process &

That terminal is now long closed, but process is still running, and I want to send some commands to that process’s stdin. Is that possible?

Asked By: Rogach

||

I am quite sure you can not.

Check using ps x. If a process has a ? as controlling tty, you can not send input to it any more.

9942 ?        S      0:00 tail -F /var/log/messages
9947 pts/1    S      0:00 tail -F /var/log/messages

In this example, you can send input to 9947 doing something like echo "test" > /dev/pts/1. The other process (9942) is not reachable.

Next time, you could use screen or tmux to avoid this situation.

Answered By: andcoz

EDIT : As Stephane Gimenez said, it’s not that simple. It’s only allowing you to print to a different terminal.

You can try to write to this process using /proc. It should be located in /proc/pid/fd/0, so a simple :

echo "hello" > /proc/PID/fd/0

should do it. I have not tried it, but it should work, as long as this process still has a valid stdin file descriptor. You can check it with ls -l on /proc/pid/fd/.

  • if it’s a link to /dev/null => it’s closed
  • if it’s a link to /dev/pts/X or a socket => it’s open

See nohup for more details about how to keep processes running.

Answered By: Coren

Yes, it is. First, create a pipe:
mkfifo /tmp/fifo.
Use gdb to attach to the process:
gdb -p PID

Then close stdin: call close (0); and open it again: call open ("/tmp/fifo", 0600)

Finally, write away (from a different terminal, as gdb will probably hang):

echo blah > /tmp/fifo

Answered By: Ansgar Esztermann

Just ending the command line with & will not completely detach the process, it will just run it in the background. (With zsh you can use &! to actually detach it, otherwise you have do disown it later).

When a process runs in the background, it won’t receive input from its controlling terminal anymore. But you can send it back into the foreground with fg and then it will read input again.

Otherwise, it’s not possible to externally change its filedescriptors (including stdin) or to reattach a lost controlling terminal… unless you use debugging tools (see Ansgar’s answer, or have a look at the retty command).

Answered By: Stéphane Gimenez

When original terminal is no longer accessible…

reptyr might be what you want, see https://serverfault.com/a/284795/187998

Quote from there:

Have a look at reptyr, which does exactly that. The github page has all the information.

reptyr – A tool for "re-ptying" programs.

reptyr is a utility for taking an
existing running program and attaching
it to a new terminal. Started a
long-running process over ssh, but
have to leave and don’t want to
interrupt it? Just start a screen, use
reptyr to grab it, and then kill the
ssh session and head on home.

USAGE

reptyr PID

"reptyr PID" will grab the process
with id PID and attach it to your
current terminal.

After attaching, the process will take
input from and write output to the new
terminal, including ^C and ^Z.
(Unfortunately, if you background it,
you will still have to run "bg" or
"fg" in the old terminal. This is
likely impossible to fix in a
reasonable way without patching your
shell.)

Edit claims that "reptyr cannot grab a process which has subprocesses. Or the subprocess (reptyr version 0.6.2)." Limited support does exist Issue, Issue

Answered By: NiKiZe