top | item 33086322

How to move a running process into a tmux session (2020)

307 points| s0l1dsnak3123 | 3 years ago |xai.sh

50 comments

order
[+] mindwok|3 years ago|reply
I was curious how this worked so I did some reading which I found interesting. In short, this uses ptrace, which is the same Linux kernel mechanism used by debuggers, to attach to a running process and manipulate the open file descriptors (amongst other things) while it runs. So basically it attaches to the process, and changes stdin (fd 0) and stdout (fd 1) to point to your tmux session stdout and stdin.

Pretty cool use of ptrace.

[+] eftychis|3 years ago|reply
This is pretty cool! I had done something similar to connect isolated processes on the fly last year. But never thought to do that with tmux as a target.
[+] ynbl_|3 years ago|reply
yes i didnt think theres a way to do this without hacks. unportable and fragile as expected.
[+] kennu|3 years ago|reply
It's a nice tool (reptyr), but not particularly convenient to use, requiring several steps to move the process to the background and remembering the PID etc. I do wish this was a more streamlined, standard feature of Unix/Linux shells. Something like a simple integrated "pushproc"/"popproc" command.
[+] CGamesPlay|3 years ago|reply
Seems not super hard to do. A shell function could do the bg, disown, and use the tmux remote API to start a new window and remotely execute reptyr in it.
[+] kleiba|3 years ago|reply
"Do one thing and do it well."
[+] jcynix|3 years ago|reply
The streamlined version is what "screen -d …" does, so it's some kind of standard feature, isnt it?. The only "drawback" I see is that you have to plan ahead to use screen.

When I start long running jobs, I try do start them that way, so I can check on them (and their output in a screen logfile) from anywhere:

screen -L -Logfile "batch-xyzzy-221005a" -S "xyzzy1" bash job.sh

Now I can just check the log with grep or less, or reattach to it if some action is needed.

[+] outworlder|3 years ago|reply
> Take away the ownership from the shell using disown

Interesting. So far, my only ever use of disown was to decouple GUI apps that I launched from the terminal. I do that automatically now, as it's annoying when you forget, close the terminal, and a bunch of apps go away.

[+] severino|3 years ago|reply
Just for curiosity: what was the purpose of "disown"? If I recall correctly, it was used so the shell you used to launch the process didn't kill it using a "hang" signal or something like that. But I made a quick test and my shell doesn't seem to kill the background process launched from it, at least when I quit using ctrl + d.
[+] jagged-chisel|3 years ago|reply
How does this compare to using

    nohup <gui-app> &

?
[+] jaimehrubiks|3 years ago|reply
As others said, wish this use case had been considered on Unix based OSs. I guess it's a very common issue many people have daily. I don't like to do it but some people have some bashrc or ssh config script to auto attach every session to a tmux session or even docker container.
[+] cawwot|3 years ago|reply
This is standard practice for systems following STIGs. Bashrc is required to enforce that new sessions always get a tmux and stay in the tmux session.
[+] hinkley|3 years ago|reply
On a multi user system this seems fraught. That’s probably why it didn’t happen sooner.
[+] _kst_|3 years ago|reply
I tried this on Ubuntu 22.04.1 and got an error:

    $ reptyr 10330                                                                                                                                                
    Unable to attach to pid 10330: Operation not permitted 
    The kernel denied permission while attaching. If your uid matches
    the target's, check the value of /proc/sys/kernel/yama/ptrace_scope.
    For more information, see /etc/sysctl.d/10-ptrace.conf
    $ 
I haven't (yet) looked into how to fix or work around this problem.
[+] tyingq|3 years ago|reply
Either, as root:

# echo 0 > /proc/sys/kernel/yama/ptrace_scope

or permanently by editing the file /etc/sysctl.d/10-ptrace.conf

[+] leni536|3 years ago|reply
> It’s rare, but sometimes it still happens that I forget to open a tmux or screen session when working with something that is supposed to be quickly done.

There are various ways to get ahead of this problem too if you ssh into a tmux session automatically. There are various ways to achieve this.

I didn't know about reptyr, it's very cool. There were times I wished this was possible, but whenever I searched for a solution I got "It's not possible". Oh well...

[+] susam|3 years ago|reply
Yes! I have a shell function that automatically attaches to an existing tmux session or creates a new tmux session if none exists already, after logging into the remote system via SSH:

  ssht() {
      ssh -t $1 'tmux a || tmux'
  }
[+] planede|3 years ago|reply
I have an autossh + tmux setup. It's along the lines of

  autossh -M 0 -t remote "tmux new-session -A -D -s $RANDOM$RANDOM$RANDOM$RANDOM"
with appropriate ServerAliveInterval and ServerAliveCountMax settings. It works somewhat nicely with dodgy ssh conncetions too. I'm aware of mosh, but this one even outlives when I put the laptop to sleep. Also mosh doesn't allow X forwarding, and I enable that for sharing the clipboard (yes, I'm aware of the security implications). And if I want to leave something long-running, I can just close the window and reattach later.
[+] amelius|3 years ago|reply
One problem of course is that you miss the output of the process from before you took over control. Perhaps shells could be extended to better support this way of using tmux/screen.

By the way another approach is of course to use VNC (e.g. some process started in an xterm at work you can access by opening your entire desktop at home.)

[+] linsomniac|3 years ago|reply
Doesn't really feel like the shell would be the right place to do this, as the shell really has no idea, in most cases, of the output history. The whole idea of the scrollback is in the terminal, so it'd probably be, ultimately, the terminal that is the source of this information.

kitty probably has some abilities to do this easily from the shell, as it has all sorts of abilities to interact programmatically with the scrollback history.

[+] cryptonector|3 years ago|reply
No need to `bg` the process. The `reptyr` tool should set it to run once it's gotten ptrace control over it.
[+] 1MachineElf|3 years ago|reply
I feel embarrassed to call myself a tmux fan learning this has been around since at least 2011.
[+] CoolCold|3 years ago|reply
not denying value of the article, it's great, but kinda solved problem for me - for multiple years, 99% of cases the first command after ssh login to server is `tmux attach || tmux` for me. Almost never run anything not in tmux/screen.
[+] chisquared|3 years ago|reply
I think you can just do `tmux new -A`. IIRC this is equivalent to `tmux attach || tmux`.
[+] ivanb|3 years ago|reply
The ability to attach a detached process to any terminal should be a coreutil.
[+] tpoacher|3 years ago|reply
Unrelated to the article, but my favourite tmux trick is joining an existing tmux session to use as a collaborative (terminal) environment over ssh.

Remote pair coding made fun again!

[+] johnklos|3 years ago|reply
Very cool! I hope this becomes a standard feature of all common Unix OSes. Will have to look at what part of this is architecture specific so it can be properly abstracted.
[+] green-salt|3 years ago|reply
I can think of several instances in the past where I wished I could have done this. Learning about screen back in 2007 was life changing.
[+] meatjuice|3 years ago|reply
The problem is, however, it works ONLY on Linux.
[+] vasvir|3 years ago|reply
Very cool. Thanks for posting this. I tried with screen and I can confirm that it also works.
[+] mateusfreira|3 years ago|reply
Amazing short post ... Yesterday I needed this, what a coincidence!!