When you disown
a process in Linux, you're essentially detaching it from your current shell session while allowing it to continue running. This is useful when you need to disconnect from a remote server but want to keep a long-running job alive. However, this leaves the process orphaned without its original STDIN/STDOUT/STDERR handles.
The most straightforward method is using reptyr
, a tool specifically designed for this purpose:
# First install reptyr
sudo apt-get install reptyr # Debian/Ubuntu
sudo yum install reptyr # CentOS/RHEL
# Find your process ID
ps aux | grep your_process_name
# Reattach the process
reptyr PID
For systems where reptyr
isn't available or doesn't work, you can use GDB:
# Attach GDB to the process
gdb -p PID
# In GDB:
(gdb) call dup2(open("/dev/pts/X", 0), 0)
(gdb) call dup2(open("/dev/pts/X", 1), 1)
(gdb) call dup2(open("/dev/pts/X", 2), 2)
(gdb) detach
(gdb) quit
Replace X with your actual terminal number (find it with tty
command).
If you originally ran the process in screen or tmux, you can try these approaches:
# For screen:
screen -r
# For tmux:
tmux attach
For daemonized processes or those that have closed their file descriptors:
- Check if the process supports signal-based reopening of logs (like nginx -USR1)
- Consider using
strace
to monitor file operations - For critical processes, set up proper logging from the start
To avoid this situation in the future:
# Always use screen/tmux for long-running processes
screen -S session_name
./long_running_script.sh
# Then detach with Ctrl-A D
# Or use nohup with proper redirection
nohup ./script.sh > output.log 2>&1 &
We've all been there - you start a long-running process in a terminal, realize you need to disconnect, and hastily use disown
to keep it running. Now you're reconnected and want to monitor the process's output or provide input, but find the standard I/O streams are lost.
When a process is disowned, it loses its connection to the original terminal's file descriptors (stdin=0, stdout=1, stderr=2). These become orphaned and can't be simply reattached with tools like screen
or tmux
.
The most reliable method is using gdb
to redirect the file descriptors:
# First find your process ID $ pgrep -f "your_process_name" # Attach with gdb $ gdb -p PID # In gdb: (gdb) call close(0) (gdb) call close(1) (gdb) call close(2) (gdb) call open("/dev/pts/X", 0) # Replace X with your current terminal (see 'tty') (gdb) call dup(0) (gdb) call dup(0) (gdb) detach (gdb) quit
For a simpler solution, install and use reptyr
:
$ sudo apt install reptyr # Debian/Ubuntu $ reptyr PID
To avoid this situation in the future:
- Always use
screen
ortmux
for long-running processes - Consider
nohup
with proper redirection:nohup command > output.log 2>&1 &
- For critical processes, use proper init systems like systemd
If reattachment isn't possible, ensure your process logs to files:
$ strace -ewrite -p PID # View writes to stdout/stderr $ lsof -p PID # Check open files