For example, if I want to know the value of textwidth in vim, I can dereference it by appending a ?. Thus, I will simply type :set textwidth?.
How can you do the equivalent in tmux?
To dereference the value of a tmux setting or variable, you can run the following terminal command:
tmux display-pane -p #{<setting-or-variable-name>}
Or, to be more verbose
tmux display-pane -p "The value of your setting or variable is #{<setting-or-variable-name>}"
Example of a working command:
tmux display-message -p "You have #{display-panes-time}ms to press a number key after running 'display-pane'"
Note: The corresponding command-prompt commands, surprisingly, will fail:
:display-pane #{display-panes-time}
:display-pane #{display-panes-colour}
However, when you add quotes, they act as expected:
:display-pane "#{display-panes-time}"
:display-pane "#{display-panes-colour}"
What...?
Related
Using tmux, I'd like to run a command from one pane against another pane, and capture the output of the command.
For example, say in pane 7 I have an SSH session running, and I'd like to run a bash script in pane 2 to capture the host name from pane 7.
Is this possible?
I know I can do the send keys like so
$ tmux send-keys -t 7 "hostname" Enter
but I'm not sure how to capture the output from pane 7 into a bash variable.
I don't mind if it displays on the screen either (doesnt have to happen in the background).
EDIT: Note that hostname is just an example - I would like to run other scripts against each pane as well
As an alternative to capture-pane you can similarly use pipe-pane. It is often used for logging. You give it a command to pipe all output into, or no command at all to stop piping. So you end up with something like
tmux pipe-pane -t 7 'cat >/tmp/capture'
tmux send-keys -t 7 'hostname' Enter
sleep 1
tmux pipe-pane -t 7 # stops piping
IT=$(</tmp/capture)
Beware, this capture includes carriage-return characters. You will need to remove the first and last lines of the capture to get just the wanted output. Eg:
IT=$(sed '1d;$d;s/\r//' </tmp/capture)
While not exactly what I was looking for, the tmux capture-pane command seems to capture the displayed output of a pane, which I can run of course after running my command.
example.sh
#/bin/bash
# run the command in another pane
tmux send-keys -t 7 "hostname" Enter
# capture it's output
IT=$(tmux capture-pane -p -t 7)
echo "$IT"
I am trying to send code to SBCL directly from Kakoune. I've settled on using tmux for this, the SBCL instance runs in a tmux instance with a given session name. The tmux command for passing in the key inputs is as follows:
tmux send-keys -t <session-name> "<text to send to tmux>"
In kakoune, however, it seems that the most convenient existing ways to pass selections' text into an external command is through piping, not as an argument. For now this seems to work:
nop %sh{tmux send-keys -t sess -l "$kak_selection"}
This kind of does what I want, but it only sends the primary selection. I cannot really use $kak_selections because this adds single quotes to the selections, which would not be parsed as intended by SBCL. Even if it didn't, I'd prefer if it behaved more like alt+|, which pipes the selections into their own instances of the command. Is there an existing way in Kakoune to do this? If not, would it be easy to write an sh script that would convert the stdin to a quoted argument for tmux?
I was unable to find any built-in way to do this, but this question/answer helped: Piping result of command as an argument
I ended up settling on this command to be run externally (so that I can use the default piping behavior in Kakoune)
xargs -0 tmux send-keys -t sbcl -l "${#}"
If I have an operation such as
ps -u $USER -o pid,rss,command
is there a way I can assign this to a variable so that I do not have to type it out every time?
If you want to save the command and replay it often, you can make an alias:
alias myps='ps -u $USER -o pid,rss,command'
Now, you can re-run the command by typing:
$ myps
You can also store this in your .bashrc file or .bash_profile.
On the other hand, if you have GNU readline available, you might get by with something like this: Ctrl+R ps -u
Ctrl+r does a history lookup; all you have to do is type a unique portion of a command, and then press Enter to execute it; or press Ctrl+C to abort.
What it comes down to is, I would like to
print a variable unique to the window ,or
run a script unique to the window
and use the output in the status bar such that each window status is unique. I've tried to make it more clear through 2 scenarios:
Scenario 1
I'm trying to print a unique per window variable in the status bar. I've opened a shell inside tmux and have stored the tmux environment variable locally (per session) and globally (for all sessions) with the following commands, respectively:
bash> tmux set-environment TMUX_STATUS_1 localvalue1
bash> tmux set-environment -g TMUX_STATUS_1 globalvalue1
I can verify these values for instance by going the another shell (in the same session) and typing:
bash> tmux show-environment TMUX_STATUS_1
TMUX_STATUS_1=localvalue1
bash> tmux show-environment -g TMUX_STATUS_1
TMUX_STATUS_1=globalvalue1
I've tried to print the above value in the statusbar (both the local and global value) and have configured the window format as follows:
WINDOW='[#(tmux show-environment -g TMUX_STATUS_#I 2>&1)]'
setw -g window-status-current-format $WINDOW
setw -g window-status-format $WINDOW
Initially it only showed windows as '[]', after this I added the redirection of stderr to stdout and got the status bar showing the following:
[unknown variable: TMUX_STATUS_1] [unknown variable: TMUX_STATUS_2] [...
What needs to be changed to make the statusbar show (according to previous commands):
[globalvalue1] [unknown variable: TMUX_STATUS_2] [...
PS: it's not a status bar refresh issues, as i've used the following command after setting the variable to manually force a refresh of the statusbar:
tmux refresh-client -S
Scenario 2
I've written a small bash script called 'tmuxscript' containing only:
echo "$(date '+%S') window:$(tmux display -p '#I') args:$#"
I updated my PATH variable and I have changed the window format to '[#(tmuxscript arg1 #I)]'. The output looks like:
[47 window:1 args:arg1] [47 window:1 args:arg1] [...
The time updates nicely. Printing the window index inside the script doesn't seem to work. The number 1 represents the window index of the currently focused window. This value is set for all windows, which is not what I want. I would at least expect to see (note the window index number) :
[47 window:1 args:arg1] [47 window:2 args:arg1] [...
Also, #I isn't getting past to the script, but the text 'arg1' is. How can I pas tmux variables to the script?
EDIT: I have now also tried setting the window status to:
'[#(tmux show-environment -g TMUX_STATUS_$\(tmux display -p "#I"\) 2>&1 | sed "s:^.*=::" )]'
Which gives me the following when the active (focused) window index is 1:
[globalvalue1] [globalvalue1] [...
Any help is appreciated!
Ok, I figured it out.
The problem lies in the fact that you are obligated to use the -g (global) flag when specifying a window-status in .tmux.conf.
.tmux.conf:
WINDOW="[#I #20W]"
set-window -g window-status-current-format $WINDOW
set-window -g window-status-format $WINDOW
The key is to make the status local after creating a window. Also, each window needs to be uniquely identifiable. Luckily this can be done by tmux variable 'window_id'. A small script, shown below, will output a variable unique to the window with this id as its first argument:
~/tmuxstatus:
#!/bin/bash
VARIABLE="W_$1"
VALUE=$(tmux show-environment -g $VARIABLE 2>&1)
VALUE=${VALUE#*=}
echo $VALUE
There is probably a TMUX only solution to make the status local, but I don't currently have the time. I'm using bash to do it with the aid of the environment variable PROMPT_COMMAND, which is evaluated just before the prompt is shown.
.bashrc:
function __prompt_command (){
if [ -n "$TMUX" ] && [ ! -n "$TMUX_INIT" ]; then
W=$(tmux display -p '#{window_id}')
VARIABLE="W_$W"
VALUE="value_$W"
STATUS="[#I #(~/tmuxstatus $W)]"
tmux set-option quiet on;
tmux set-environment -g $VARIABLE $VALUE;
tmux set-window window-status-current-format "$STATUS";
tmux set-window window-status-format "$STATUS";
export TMUX_INIT="done";
fi;
}
export PROMPT_COMMAND=__prompt_command
When changing the value of W_id, the window status changes also. It looks like:
[1 value_#0] [2 value_#1] [3 value_#2] [4 value_#3]
enjoy!
Perhaps using the echo command you can manually set the title using this syntax:
echo -ne "\033]0;$(tmux show-environment TMUX_STATUS_1)\007"
Try running that in different TMUX windows and see if it changes the title.
i know tmux display-message -p '#S' will display the current tmux session name, but i donno how to set the current tmux session name to the iterm2 tab title?
This would really help me to distinguish the various tmux sessions that i am running concurrently and jump to the correct tab rightaway.
add these to your ~/.tmux.conf:
set-option -g set-titles on
set-option -g set-titles-string "#{session_name} - #{host}"
My workflow is usually centered around panes, and I don't use tmux, so I used a slight variation of #mislav answer:
set_terminal_tab_title() {
print -Pn "\e]1;$TABTITLE:q\a"
}
precmd_functions=($precmd_functions set_terminal_tab_title)
I threw that into my zshrc; then, in each pane, I export TABTITLE='FOO'. That way, when I switch panes, I get the title I want on the tab.
Stick this in your ~/.zshrc:
set_terminal_tab_title() {
print -Pn "\e]1;$1:q\a"
}
indicate_tmux_session_in_terminal() {
set_terminal_tab_title "$(tmux display-message -p '#S')"
}
precmd_functions=($precmd_functions indicate_tmux_session_in_terminal)
precmd_functions is an array that in zsh contains the list of functions to call prior to showing the prompt. If you add your own function to the list, it will get called whenever the prompt is shown, making it a good place to periodically update the terminal tab title.
Bash Version to display Hello World as a title:
echo -ne "\033]0; Hello World \007"
And if you want title refreshed each time bash print your prompt:
export PROMPT_COMMAND='echo -ne "\033]0;${USER}#${HOSTNAME%%.*}: ${PWD/#$HOME/~}\007"'
Found it on http://hints.macworld.com/article.php?story=20031015173932306