What reptyr Does
Installation
Basic Usage
The Common Scenario: Forgot to Start tmux
The ptrace_scope Problem (Ubuntu)
Advanced: reptyr -l
When It Won't Work
Summary
References You SSH'd in and started a job that will run for hours. No tmux. No nohup.
Now you need to leave, and closing the window kills the process.reptyr moves it into tmux so you can disconnect safely. reptyr uses the ptrace syscall to re-attach a running process to a new terminal. It genuinely changes the process's controlling terminal — not just redirecting I/O. That distinction matters. Old gdb-based scripts like "screenify" can do something similar, but with three problems: reptyr fixes all three because it actually replaces the controlling terminal. The process attaches to the current terminal and receives its input, output, and signals (Ctrl-C, Ctrl-Z all work). The process is still running, output intact. Ubuntu 10.10+ disables non-root ptrace by default. reptyr will fail with: Temporarily allow it: Or just run sudo reptyr <PID>. [!NOTE]
ptrace_scope values: 0 = allow all, 1 = parent-only (default), 2 = root only, 3 = disabled. Setting it to 1 is enough for reptyr to work if you own the process. Creates a detached pseudo-terminal pair not connected to any shell. Useful for gdb: Cleaner than handing gdb your terminal directly. Forgetting tmux isn't fatal. reptyr <PID> moves a process from a dying SSH session into tmux in one command. disown it first to cut the shell's hold, then open tmux and pull it in. On Ubuntu, adjust ptrace_scope as needed. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse
# Ubuntu / Debian
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install reptyr # Arch
-weight: 600;">sudo -weight: 500;">pacman -S reptyr # From source
-weight: 500;">git clone https://github.com/nelhage/reptyr
cd reptyr && make && -weight: 600;">sudo make -weight: 500;">install
# Ubuntu / Debian
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install reptyr # Arch
-weight: 600;">sudo -weight: 500;">pacman -S reptyr # From source
-weight: 500;">git clone https://github.com/nelhage/reptyr
cd reptyr && make && -weight: 600;">sudo make -weight: 500;">install
# Ubuntu / Debian
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install reptyr # Arch
-weight: 600;">sudo -weight: 500;">pacman -S reptyr # From source
-weight: 500;">git clone https://github.com/nelhage/reptyr
cd reptyr && make && -weight: 600;">sudo make -weight: 500;">install
reptyr <PID>
reptyr <PID>
reptyr <PID>
# 1. Find the process PID
jobs -l
# or
ps aux | grep my-script # 2. If it's in the foreground, suspend it
Ctrl-Z # 3. Move it to the background
bg # 4. Detach it from the current shell (so the shell dying won't kill it)
disown # 5. Start tmux
tmux new -s rescue # 6. Pull the process into tmux
reptyr <PID> # 7. Safe to disconnect now
Ctrl-B D # detach tmux
# 1. Find the process PID
jobs -l
# or
ps aux | grep my-script # 2. If it's in the foreground, suspend it
Ctrl-Z # 3. Move it to the background
bg # 4. Detach it from the current shell (so the shell dying won't kill it)
disown # 5. Start tmux
tmux new -s rescue # 6. Pull the process into tmux
reptyr <PID> # 7. Safe to disconnect now
Ctrl-B D # detach tmux
# 1. Find the process PID
jobs -l
# or
ps aux | grep my-script # 2. If it's in the foreground, suspend it
Ctrl-Z # 3. Move it to the background
bg # 4. Detach it from the current shell (so the shell dying won't kill it)
disown # 5. Start tmux
tmux new -s rescue # 6. Pull the process into tmux
reptyr <PID> # 7. Safe to disconnect now
Ctrl-B D # detach tmux
ssh yourserver
tmux attach -t rescue
ssh yourserver
tmux attach -t rescue
ssh yourserver
tmux attach -t rescue
Unable to attach to pid 12345: Operation not permitted
Unable to attach to pid 12345: Operation not permitted
Unable to attach to pid 12345: Operation not permitted
echo 0 | -weight: 600;">sudo tee /proc/sys/kernel/yama/ptrace_scope
echo 0 | -weight: 600;">sudo tee /proc/sys/kernel/yama/ptrace_scope
echo 0 | -weight: 600;">sudo tee /proc/sys/kernel/yama/ptrace_scope
# Edit /etc/sysctl.d/10-ptrace.conf
kernel.yama.ptrace_scope = 0
# Edit /etc/sysctl.d/10-ptrace.conf
kernel.yama.ptrace_scope = 0
# Edit /etc/sysctl.d/10-ptrace.conf
kernel.yama.ptrace_scope = 0
reptyr -l
# Outputs: /dev/pts/7
reptyr -l
# Outputs: /dev/pts/7
reptyr -l
# Outputs: /dev/pts/7
(gdb) set inferior-pty /dev/pts/7
(gdb) set inferior-pty /dev/pts/7
(gdb) set inferior-pty /dev/pts/7 - The old terminal still delivers input to the process
- Window resize events don't reach ncurses applications
- Ctrl-C from the new terminal doesn't work - Daemon processes: already detached from any terminal — nothing to re-attach to
- setuid binaries: ptrace can't attach (security restriction)
- Dead processes: obviously not salvageable - reptyr GitHub repository
- tmux official GitHub repository
- Linux Yama ptrace_scope security documentation
- tmux manual page