Is there a way to show the command which is currently running at a tmux pane?
I tried 'history', but it does not seem to show the commands which I had executed at tmux.
I also tried 'ps -ef', but it does not show the full command in the case like "./a.sh ; ./b.sh"
I found several answers online that include ps ... | tail -1. Unfortunately, these don't always work because sometimes the order of the commands is swapped, e.g. for two separate panes I get:
$ ps -t /dev/pts/12 -o args=
-bash
mpv some_movie.mp4
$ ps -t /dev/pts/10 -o args=
micro some_file.txt
-bash
I really wanted a single line of output so that I could show it in the status bar, but what I ultimately ended up going with is ps --forest via run-shell. It seems to always reliably show the correct order and with more information should there be nested commands running (e.g. via a bash script). Its output looks like:
$ ps --forest -o args -g $$
COMMAND
-bash
\_ ps --forest -o args -g 1695
Solution
So in my .tmux.conf, I've got:
bind '`' run-shell 'ps --forest -o pid,args -g #{pane_pid}'
It will replace the contents of your pane with the output from the ps --forest command. Once you type esc or ^C, the ps output disappears, and your pane goes back to whatever it was doing :) Ends up looking like:
running script.sh, which calls other-script.sh, which sleeps for 30s
viewing pane process tree via keybinding
(Old question but for future reference)
Try: tmux list-panes -t <your_pane_name> -F '#{pane_current_command}'
https://man7.org/linux/man-pages/man1/tmux.1.html#FORMATS
Try setting pane-border-status to bottom or top in your configuration file, with the tmux command prompt or just running tmux set pane-border-status bottom. Borders should appear around the panes and info about the current process appears much like in a regular terminal window's title bar.
I suspect the command wasn't written to the history file as the shell with the stuck/long-running job wasn't done yet.
You might try pstree -U to see process in their parent/child tree.
Related
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.
In my .tmux.conf I have those lines:
set -g default-terminal "xterm-256color"
set-option -g default-shell /usr/bin/fish
bind -n M-I run "fish_prompt"
But pressing M-I I get error 127 as response. Ordinary bash functions like echo 123 works fine, only fish functions are not found.
default-shell sets the shell to use in a new pane; it doesn't affect the shell used by the run-shell command, which remains /bin/sh.
As explained above, run-shell always uses /bin/sh (as defined by _PATH_BSHELL in tmux's source).
To run a fish shell, you can use run "fish -c fish_prompt", but that mucks up the escape characters and produces the output in a not-terribly-helpful way.
What output do you want to see - are you using fish_prompt or some other function?
I daily use tmux (2.5) on my laptop to work, and my tmux sessions have a starting directory which is the working directory I started the tmux session from. Every pane/window I open start with this starting directory as working directory.
I can change this starting directory, and this change would apply to the whole session.
But if I want to work on a different project with several panes, I could start a new window, but every pane I would open in it would start with the session's starting directory : I would have to cd to the new location for each pane which isn't practical.
If I need to work on several project/directories simultaneously, I can start a new terminal session, then cd to the relevant directory/project and start a new tmux session. That's not complicated.
But if I want to do the same thing on a server through ssh, I'd need to either :
open a new ssh session.
either embed my remote tmux sessions in an other tmux session.
Neither sounds practical to me, I'd prefer a single tmux session on the remote machine.
I think it would be more convenient to being able to start new window with its own starting directory location that would apply to any new pane opened in it. Is there a way to achieve this?
Edit :
I already tried the -c parameter of tmux new-window command.
But it doesn't assign its starting directory to the window created this way, it only applies this custom starting directory to the first pane created.
Any new pane opened in this window then uses the session's starting directory as default working dir (and not the path passed to tmux new-window).
This question is very similar to: https://unix.stackexchange.com/questions/12032/create-new-window-with-current-directory-in-tmux
It depends on your tmux version but the -c parameter does do the trick but it does not remember the setting. There used to be a default-path setting but that has been removed in version 1.9 unfortunately.
For newer versions you will need to pass along the -c in all cases (you can use an alias if you manually execute that command) or if you use key bindings you need to rebind the split/new window keys.
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"
To use a custom path instead of the current pane path, execute this command:
tmux setenv custom_path /home/whatever/some/path
Put this in your config:
bind '"' split-window -c "#{custom_path}"
bind % split-window -h -c "#{custom_path}"
bind c new-window -c "#{custom_path}"
Yes, it turns out the -c option to the new-window command is what you are looking for: https://unix.stackexchange.com/questions/12032/create-new-window-with-current-directory-in-tmux Also, this: https://unix.stackexchange.com/questions/101949/new-tmux-panes-go-to-the-same-directory-as-the-current-pane-new-tmux-windows-go
So either of tmux new-window -c $(pwd) or tmux new-window -c /path/to/dir inside your tmux session should do it.
I am trying to find the cpu utilization of a process from top.So before that I had to test the below command
top -b -c -d1 -n2
I am using -c option to print the full command name as the process name gets truncated without -c.
No when I run this as nohup sh test.sh & ,the output nohup.out contains truncated process name and because of which I am not able to grep on the process name
159 neutron 30 0 127620 22765 5479 S 0.0 0.6 399:02.56 /usr/bin/p+t
But when I run this as sh test.sh & its printing the full command name to terminal.
Why is the full command name not printed in spite of using -c in batch mode for top command ?
Whats the difference between command name with -c enabled and process name ?
Or to phrase it the process name and command name are different and the process name is picked from /proc/pid/status by commands like ps or top?
We can set the COLUMNS environment variable before the top command to increase the available width.
COLUMNS=1000 top -b -c -d1 -n2
The other way would be is to use ps to find the pid's of the processes by their names and specify the format of ps output.This output can be used to feed top to get the cpu usage for the process based on pid.
ps -eo pid,comms,args
comms = command name only and not the args
args = full argument list used to launch the process
Can I set tmux to trigger an alert in a non-active window when a process completes?
For example: I start a long build process. I would like to be notified when it completes, not each time it prints a status.
I'm surprised this answer hasn't been given yet: You can use the tmux window setting visual-bell for this. With bell-action you can then configure whether you want to see bells for the current window only, or for non-current window only (other). Personally I prefer the second, as you won't see noise generated by the shell, and you probably don't care about the notification if it's in the current window.
set-window-option -g visual-bell on
set-window-option -g bell-action other
When a process generates a bell, tmux will highlight the the title of the window that rings the bell as well as show a "Bell in window X" notification.
Then ring the bell at the end of the process. E.g.:
make; echo -e '\a'
(or && || instead of ; if you want to ring only on success or failure respectively)
There 3 solutions I know, none really ideal. You may put those commands in your ~/.tmux.conf or just run them directly as Tmux command via Ctrl-B :.
Monitor and alert whenever the output changes (you may then redirect output somewhere else so that output changes only after the command is complete):
:set -g visual-activity on
:setw -g monitor-activity on
Monitor and alert whenever the output did not change for a while (30 seconds here):
:set -g visual-silence on
:setw -g monitor-silence 30
(deprecated and someday replaced by a better option) Monitor and alert whevener the output contains a string matching given pattern (and possibly run your command like my-command; echo foobar):
:set -g visual-content on
:setw -g monitor-content foo*bar
$ some-command; tmux display-message "Task 1 done". However the message will only show for a short duration defined via :set -g display-time 4000.
If you keep the visual-* to off (default), it'll only highlight the name of the window in which the alert occurred without showing a global alert status message.
For details about each of these settings, see tmux man page
Updated (thanks for Steven Lu)
I finally found a solution that works for me. I use zsh for my shell, which has a feature called "Hook Functions" -- shell functions that execute on certain actions: http://zsh.sourceforge.net/Doc/Release/Functions.html.
It's likely other shells have a similar feature.
The hook function I use is precmd, which is executed each time the prompt is shown. ie, when a command has just finished running.
In my .zshrc:
precmd () {
echo -n -e "\a"
}
This sends a bell to tmux, which causes it to highlight just the window that the command was running in.
If you are already focused on that tmux window, this does nothing because the bell is immediately cleared.
The benefit of this approach is that it does not trigger on all visual activity. It only triggers when a command completes.
you can wrap your running script with a && bash derivative which will call a tmux command to notify you.
using && means you will only get notified when the script exits with error code 0. if you want it to notify you anyway, just use ;
as for the tmux commands to wrap the script, have a look at those bunch, they should suffice
select-window
split-window -h 'exec echo...'
send-keys
For future reference, people can also checkout the tmux-notify plugin, created by ChanderG, which was designed for this purpose.
Disclaimer: I'm a contributor to this plugin. Feel free to check it out and open an issue/pull request or feature request if you find a bug or see something that is missing.
there are two options:
set -g visual-activity on
setw -g monitor-activity on
have you tried setting them in your tmux.conf?
As a good workaround, you can use:
https://github.com/tcreech/tmux-notifications
You simply do:
$ command ; tmux-notify
You will get a nice notification in the status-bar (if enabled)
Building on #psp940's answer (where StackOverflow won't let me add a comment):
precmd () {
echo -n -e "\a" >$TTY
}
If you're using powerlevel10k's instant prompt feature, redirecting the bell directly to the terminal avoids a warning about pre-init console output. See also here.
Adding onto the answers from #wump and #psp940; I've found that the simplest way to be alerted any time a command completes is to put a bell in your PS1:
in tmux.conf
set-window-option -g visual-bell on
set-window-option -g bell-action other
In your .bashrc:
# ring bell every time a command completes
export PS1+=$'\[\a\]'
I'm not sure whether the += and $'' are bash-isms, but the principle will work in any shell.
The surrounding \[+\] tell your shell that the characters between them are zero-width