How do I attach a terminal to a detached process?
Solution 1
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
Solution 2
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
Solution 3
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.
Solution 4
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).
Solution 5
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.
Related videos on Youtube
Rogach
Updated on September 18, 2022Comments
-
Rogach over 1 year
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?-
Admin about 12 yearspossible duplicate of How can I disown it a running process and associate it to a new screen shell?
-
Admin about 12 yearsSearch for
retty
,neercs
, etc. and see also serverfault.com/questions/24425, serverfault.com/questions/115998 -
Admin about 3 yearsEasiest way (if you are still in same terminal) is to run
jobs
(to see, if process is still running) and if yes, usefg
to being it to foreground. After that, you can start sending commands and you will also receive stdout data. PS: "sending it to background again" can be done usingCTRL+Z
(suspend) and than runningbg
(run last job in background). See some tutorials for this topic to learn more.
-
-
manatwork about 12 yearsOr
dtach
if you not need a wholescreen
. -
Stéphane Gimenez about 12 yearsAnd there is a related question here: unix.stackexchange.com/q/17648/9426
-
Stéphane Gimenez about 12 yearsIt's not that simple. For example, If stdin is linked to a terminal,
echo
ing something to the terminal device will just print what you wrote on the terminal, it will not be transmitted to the process. -
serb about 12 years@Rogach stated "That terminal is now long closed".
-
Samuel Edwin Ward about 12 yearsVery impressive!
-
dmckee --- ex-moderator kitten about 12 yearsThere is no way in the standards (POSIX, SUS), but on many (most?) systems it is possible using the mechanisms that debuggers use. See Ansgar's answer. With
root
you could even do this to other user's processes. -
rustyx over 9 yearsCan I do something similar to redirect process stdout to a file?
-
tiwari.vikash over 9 years@rustyx: Untested, but this should work: create a file rather than a pipe,
touch /tmp/thefile
. Stdout is 1, socall close (1)
; also, use the correct permissions for writing:call open ("/tmp/thefile", 0400)
. Theecho…
is, of course, not needed. -
psmears over 9 yearsDoing
echo "test" > /dev/pts/1
won't send input to process9947
- it will output the word "test" on that process's terminal. -
krb686 almost 9 yearsThis is great! I'm using this to send "y" or "n" responses to certain processes that have been completely detached. The detached process has its stdout to a separate window. When I do this trick however, I can see that it does not "receive" the 'y' or 'n' as soon as I echo it, I must quit gdb and detach it and then it receives all of the echos accordingly, so is there a way to perform this without needing to quit gdb before the process receives the input from the fifo?
-
Aquarius Power over 8 yearshere, disown only really works if I first redirect stdout like with
>>/dev/stderr
, otherwise, when I close the terminal, the "disowned" process will end too.. I never really understood this tho.. -
archer over 5 yearsunfortunately it just seem hung on
call open("/tmp/fifo", 0600)
. any help would be greatly appreciated -
AshkanVZ almost 5 yearsi think you should use
continue
command of gdb to continue its process after doing the commands given to it -
Gary over 4 yearsIf it's not installed, try
sudo yum install -y reptyr
. This worked great for me to take over avi
editing session I lost when my SSH connection dropped (just had to press^L
after taking it back over to see all my changes and continue editing). -
miigotu about 4 yearsI did not have this installed, and could not use the package manager because the process I was disconnected from was dpkg. I downloaded the deb (pkgs.org/download/reptyr), did a
dpkg-deb --extract reptyr_0.6.2-1.2_amd64.deb reptyr && reptyr/usr/bin/reptyr $PID_OF_WANTED_PROCESS
-
d9ngle about 4 yearsis this still valid? unfortunately does not work for me (ubuntu 18)
-
TripeHound about 4 yearsDid essentially the same as @miigotu: downloaded (what I hoped was) the right package from pkgs.org/download/reptyr and extracted
reptyr
... was able to save a file from a detached VI session. -
Mark Plotnick over 2 yearsI believe this should be
call open ("/tmp/fifo", 0)
(Open for reading.) 0600 would be appropriate for a third argument toopen
if the second argument has the O_CREAT (0100) flag. Using 0600 as a second argument, it's O_RDONLY|O_EXCL|O_NOCTTY on Linux, which seems to be OK, but O_EXCL without O_CREAT is undefined (unless the file in a block device).