Is it possible to quit tmux, while "keeping" the window in the terminal - tmux

Use case
I run command over a bastion in SSH and since the connection can be dropped we are using tmux or screen.
For short commands I'm using send-keys, let's say I'm using a command like kubectl get pods. I'd like to keep the output of this command but terminate the tmux session.
Using remain-on-exit is not what I'm looking for as it keeps a dead window.
I've seen those question already
https://unix.stackexchange.com/questions/17116/prevent-pane-window-from-closing-when-command-completes-tmux
TMUX: how to make new window stay when start shell-command quits?

I'd like to keep the output of this command but terminate the tmux session.
I use this in my ~/.tmux.conf, and now when I exit my running shell, pane output is saved to unique log file:
set -g remain-on-exit
set-hook pane-died 'capture-pane -S - -E - ; save-buffer "$HOME/logs/tmux/tmux-saved.#{host_short}-#{session_id}:#{window_id}:#{pane_id}-#{pane_pid}-#{client_activity}.log"; delete-buffer; kill-pane'

I'm not sure it's exactly what you are looking for, but you could use the capture-pane command to save the contents of a pane (subject to what is still in the pane's history) to a file.

Related

Having an interactive menu when running a shell command

I have this line in my .tmux.conf file.
bind-key q run "fish --interactive -c q"
The code for function q is written in fish. This is the code.
function q
set session (t ls | fzf)
set chosen (string split ":" $session)
t switch -t $chosen[1]
end
What q does is simple. Pipe the output from the output for t ls, which is tmux ls, into fzf. Then split the string by : and then switch tmux sessions.
When I run q normally as a command in fish, it works fine. The fzf ui shows up and I can switch sessions.
But when I use the keybinding I set. It lets me change sessions but an interactive window does not appear. It just switches sessions without letting me choose.
What I want is to be able to have an interactive menu when I use prefix-q. So that I can choose which session I want to switch to.
When tmux invokes your bind-key shell command, it does so without any tmux pane active. That is, it runs the shell detached from any tty, because a tmux command might switch panes, or create a new pane, or destroy one; so it runs in a void.
The right idea is use tmux bindings to control tmux, and shell bindings to run commands in the current shell instance, which may in turn talk to tmux. Try this (as a shell command, not in tmux.conf):
bind \cTb q
This is a shell binding. Now 'control-T' followed by 'b' will run the menu in whatever pane is active.
The problem is the command capture alters the stdin/stdout/stderr file descriptors that fzf is handed. Try forcing it to interact with the tty:
set session (t ls | fzf 2>/dev/tty)

Tmux session does not always open with expected mount bindings

I want to run unshare, mount a few directories, and run a tmux session in the new mount namespace. Here is my setup
$ cat run
#!/bin/bash
mount --bind ~/a ~/b
tmux
$ unshare -r --mount ~/run
When I run this command, I get dropped into the tmux session but without the binding. What is more strange to me is that if I rerun the mount command in the tmux session and exit, the next time I run unshare -r --mount ~/run the binding is there!
I could get consistent behavior by always running the mount command in the tmux session but I would like to understand why the behavior depends on if the binding existed in a previous session.
Replacing tmux with /bin/bash to poke at the mounted directory shows that the binding always happens, as expected. Once running the mount command in tmux, all subsequent runs have the binding until I move ~/a. Then the problem is back.
I am now unable to reproduce my own problem. I suspect the solution was to power cycle. I do not think I had done so between installing tmux and running into this issue, so that may have been the root cause.

How to use xterm to launch screen with arguments

I'm currently using mobaxterm to launch xterms to connect to a remote server. I use...
xterm screen
I use screen because the connection is unreliable so screen allows me to recover sessions.
What I really want is to call "screen -RR" to reconnect sessions if there, or start a new one, but xterm doesn't allow command line arguments.
I've played around with -e, -ls, -hold, etc but I can't get it to work.
Any ideas?
[Edit]
Additional information...
I've tried...
xterm ./script.sh
with screen -RR in it, but that runs, then exits. -l or -hold doesn't help.
xterm -e /bin/bash -c screen -RR
same problem, exits without giving me a prompt.
My current hack is...
xterm ./mybash
where mybash a sym-link to /bin/bash, and I have a check in .bashrc looking for XTERM_SHELL = mybash, then launching screen -RR, but that runs 2 bash shells, so I have to exit twice to close the window.
xterm -e should work. It takes one or more arguments specifying a command (plus its arguments) to execute under xterm (so it must be the last option).
For example, this should work
xterm -e screen -RR
There's no need to invoke /bin/bash to invoke screen.

Opening a program and then waiting for it

Is there a general way to wait for an executed process that backgrounds in fish (like open "foo")? As far as I can tell, $! (the PID of the last executed child process in bash) is not present in fish, so you can't just wait $!.
1) The fish idiom is cmd1; and cmd2 or if cmd1; cmd2; end.
2) You should find that bash and zsh also don't block if you execute open ARG. That's because open will normally background the program being run then open exits. The shell has no idea that open has put the "real" program in the background. Another example of that behavior is launching vim in GUI mode via vim -g. Add the -W flag on macOS or -w on Linux to the open command and -f to the vim command.
The key here is that open, even if it backgrounds, won't return a signal that fish will use to evaluate the and operator until something happens to the opened process. So you get the behavior you're looking for.

How do you detach a remote screen session in byobu (tmux)?

I am currently in a byobu-tmux session and am ssh'ed into a screen session. How do I detach the remote screen session without detaching byobu-tmux session? Some things to note, I can't run byobu-config because I'm on osx and don't have python-newt (w/ snack) installed. And, I've run byobu-ctrl-a in Emacs mode, but that doesn't seem to allow me to ctrl-a d out of the remote screen session.
It is easy when you use tmux commands:
byobu-tmux detach
byobu-tmux
or even just:
byobu detach
byobu
You should be able to double-escape with Ctrl-a.
To send a detach message to the inner byobu-screen session, press:
Ctrl-a Ctrl-a d
Full disclosure: I am the author and maintainer of Byobu.
Try letting go of ctrl after the first a, so the sequence is ctrl-a, a, d. Man screen:
C-a C-a (other) Toggle to the window displayed
previously. Note that this
binding defaults to the command character typed twice, unless
overridden. For instance, if you use the option "-e]x", this
command becomes "]]".
C-a a (meta) Send the command character (C-a) to
window. See escape com‐
mand.
Or if you're using tmux instead of screen for Byobu, try just ctrl-a d. Byobu's default prefix key is ctrl-b, so if you're using that default, doubling up the ctrl-a keystroke would not be necessary.
Source: https://askubuntu.com/a/309215/106100
I was able to do this by listing all clients inside the current client:
$ byobu list-clients
/dev/pts/67: 1 [80x24 xterm] (utf8)
/dev/pts/70: 1 [157x48 xterm-256color] (utf8)
Then detach the remote client (determined based on screen size):
$ byobu detach -t /dev/pts/67
Now I can use my full window size
perhaps not relevant to tmux but for byobu, I found the following command to be very helpful: detach all sessions except the current one:
/usr/lib/byobu/include/tmux-detach-all-but-current-client
hope this helps
You need to switch the prefix of your local session if it conflicts with the remote session. For example, if both are using CTRL+A then you'd be in trouble. You can either send a raw command (there's a sequence for that, but I can't remember it), or go the easy route and remap your local session to Ctrl+B, then you can input Ctrl+A that will get routed to the remote session. Also not related to tmux but the ssh connection itself you can input "~." and it'll disconnect from the ssh session. Hope it helps.
I've been an avid user of byobu on Linux for the best part of a decade. After struggling with configuring the brew install of byobu on OSX for most of these years, I finally managed to setup my byobu configs in a round about way. First I executed this:
echo '/usr/local/lib/python2.7/site-packages' | sudo tee /Library/Python/2.7/site-packages/homebrew.pth
Then I ran the byobu config file:
byobu-config
Finally I cleaned up
sudo rm /Library/Python/2.7/site-packages/homebrew.pth
Python crashed along the way with a few pop-ups, however, byobu now works for me as it should. I do need to repeat these steps when I want to change config again though... still looking for a cleaner solution.

Resources