167

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?

4
  • 2
    possible duplicate of How can I disown it a running process and associate it to a new screen shell? Commented Feb 16, 2012 at 21:38
  • 1
    Search for retty, neercs, etc. and see also serverfault.com/questions/24425, serverfault.com/questions/115998 Commented Feb 16, 2012 at 21:39
  • 2
    Easiest way (if you are still in same terminal) is to run jobs (to see, if process is still running) and if yes, use fg 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 using CTRL+Z (suspend) and than running bg (run last job in background). See some tutorials for this topic to learn more. Commented Mar 17, 2021 at 7:20
  • This question is no about attaching a terminal to a background program but how to send data to a background program; maybe the title must be changed.... Commented May 11, 2024 at 6:11

5 Answers 5

161

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

8
  • 10
    Very impressive! Commented Feb 16, 2012 at 18:59
  • 1
    Can I do something similar to redirect process stdout to a file? Commented Aug 25, 2014 at 15:28
  • @rustyx: Untested, but this should work: create a file rather than a pipe, touch /tmp/thefile. Stdout is 1, so call close (1); also, use the correct permissions for writing: call open ("/tmp/thefile", 0400). The echo… is, of course, not needed. Commented Aug 26, 2014 at 11:25
  • This 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? Commented Jul 27, 2015 at 13:50
  • 2
    is this still valid? unfortunately does not work for me (ubuntu 18) Commented Apr 9, 2020 at 19:29
60

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

5
  • If it's not installed, try sudo yum install -y reptyr. This worked great for me to take over a vi 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). Commented Jan 29, 2020 at 1:29
  • 3
    I 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 Commented Apr 3, 2020 at 5:59
  • Did 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. Commented Apr 13, 2020 at 12:57
  • 1
    In my scenario, I was able to use the newer -T argument like reptyr -T <pid> to reconnect (I was running as root already btw) Commented Dec 8, 2022 at 21:10
  • @miigotu : Thank you for this!! Just had to perform the same emergency maneuver due to nouveau driver locking up the display on a system running apt-get + dpkg-reconfigure on thousands of packages during an upgrade. Very inopportune time for nouveau kernel module to crash, but now I can SSH in and use reptyr to make sure the upgrade is complete before rebooting the system. Commented May 23, 2023 at 22:55
14

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.

3
  • 5
    Or dtach if you not need a whole screen. Commented Feb 16, 2012 at 13:32
  • 6
    There 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. Commented Feb 16, 2012 at 21:30
  • 3
    Doing echo "test" > /dev/pts/1 won't send input to process 9947 - it will output the word "test" on that process's terminal. Commented Nov 20, 2014 at 22:59
9

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).

4
  • And there is a related question here: unix.stackexchange.com/q/17648/9426 Commented Feb 16, 2012 at 16:04
  • @Rogach stated "That terminal is now long closed". Commented Feb 16, 2012 at 18:35
  • 1
    @andcoz: Yes but he's been lucky that the program has not been SIGHUPed. I was suggesting a safer method. Commented Feb 17, 2012 at 11:25
  • here, 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.. Commented Nov 20, 2015 at 5:08
8

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.

1
  • 3
    It's not that simple. For example, If stdin is linked to a terminal, echoing something to the terminal device will just print what you wrote on the terminal, it will not be transmitted to the process. Commented Feb 16, 2012 at 16:16

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.