如何根据我的会话名称自动将我的所有“tmux”会话记录到目录中的文件中?

use*_*ser 11 logs tmux

我有几个命名tmux会话。例如:

$ tmux new -s mysession1
$ tmux new -s mysession2
Run Code Online (Sandbox Code Playgroud)

我想在 my 中添加一些内容,它会根据会话名称~/.tmux.conf自动将每个会话记录到目录中的文件中。~/mytmuxsessions/例如,在上面给出mysession1mysession2创建的情况下,它将创建以下日志文​​件,其中包含我的终端窗口命令的输出(就像命令script -f file.log一样):

  1. ~/mytmuxsessions/mysession1.log
  2. ~/mytmuxsessions/mysession2.log

我尝试研究一下,发现了这一点:

  1. tmux 中是否有相当于 GNU Screen 的“log”命令?
  2. https://blog.sleeplessbeastie.eu/2019/10/28/how-to-store-the-contents-of-tmux-pane/

这些问题试图将一个键绑定到一个命令,但我希望它是自动的,即,作为我可以戴上~/.tmux.conf并忘记它的东西。例如,此命令似乎正在执行的操作是在日志文件中处理我当前的所有输出:

capture-pane -b temp-capture-buffer -S - \; save-buffer -b temp-capture-buffer ~/tmux.log \; delete-buffer -b capture-buffer
Run Code Online (Sandbox Code Playgroud)

但我想要的是类似于Linux scriptcommand 的东西script -f mysession.log,我可以将其放入 my 中~/.tmux.conf,根据我的会话名称不断将终端输出保存到日志文件中。

bba*_*025 4

我无法找到一种方法来仅使用.tmux.conf. 我所说的动态,是指根据您的情况中的会话名称,以及根据我的情况中的Unix 时间戳。但是,我能够使用tmux-logging的基本代码;我修改了源代码以获得适合我的东西。

\n

请注意,此解决方案不会将特定会话中的所有内容保存在一个日志文件中。这是可以做到的,但是将此类会话中可能存在的不同窗口和窗格组合起来会很困难。但是,此解决方案将为会话中的每个窗格保存一个日志文件,因此日志文件中将包含您的所有输入和输出。您始终可以从 派生tmux-plugins/tmux-login,或者您可以根据他们组合的内容编写自己的代码并仅使用您喜欢的代码。

\n
\n

长话短说

\n

tmux-logging从git 存储库安装tmux-plugins

\n

Change the variable definition for filename_suffix to match the format you\'d like. This should be done in /path/to/tmux-plugins/tmux-logging/scripts/variables.sh.

\n

Copy the toggle_logging.sh to another script - I called it ~/.ensure_tmux_logging_on.sh, and it is in my $HOME directory so a future update to tmux won\'t wipe it out. Change the script so that the if is_logging doesn\'t do anything (or just outputs a message). Leave the associated else branch as it is.

\n

Call your ~/.ensure_tmux_logging_on.sh from your .bash_profile (or .bash_login or .login or .profile - whichever will make sure it gets called by non-login shells). tmux always opens a non-login shell, so .bashrc won\'t work unless you source it from one of those previous scripts. See here (1), here (2), or here (3) - all three being answers to the same AskUbuntu question - for more details.

\n

Keep notes somewhere, because if an update comes for tmux-logging, you\'ll have to use the same hack.

\n

I tried to figure out a way to do this with .tmux.conf, but had trouble getting the session information, because that seemed to be set in an accessible variable after .tmux.conf had been sourced.

\n
\n

More details

\n

I used the Tmux Plugin Manager (tpm) method for installing tmux-logging, meaning I installed tpm as well as tmux-logging in one go. Here are some quick commands that do what\'s described at the READMEs of tpm and tmux-logging. Note, if you already have tpm, follow the instructions at the tmux-logging README, i.e. add the line

\n
set -g @plugin \'tmux-plugins/tmux-logging\'\n
Run Code Online (Sandbox Code Playgroud)\n

to your list of plugins in ~/.tmux.conf.

\n

You can find out if you have (at least the standard install of) tpm with this command

\n
$ test ! -d ~/.tmux/plugins/tpm && \\\n echo -e "\\n\\nYou don\'t have \\`tpm\', continue with the next commands\\n" || \\\n echo -e "\\n\\n\\\nYou have \\`tpm\'.\n\\033[0;31mPAY ATTENTION TO THIS MESSAGE\\x21\\033[0m\nFollow the instructions at\n\'https://github.com/tmux-plugins/tmux-logging/\'\nthen\n\\033[0;32mgo to the \'After getting tmux-logging\' part of the answer\\033[0m\\n"\n
Run Code Online (Sandbox Code Playgroud)\n

If you don\'t have tpm, run

\n
#(prompt can be in tmux or not)\n## It\'s best, but not necessary, to get in the directory where we\'ll be doing stuff.\nbbd025@MACHINE $ cd\n## check the existence of ~/.tmux/plugins/tpm directory, \n##+ create it if it doesn\'t exist\nbbd025@MACHINE $ test -d ~/.tmux/plugins/tpm || mkdir -p ~/.tmux/plugins/tpm\n## clone in the tpm code\nbbd025@MACHINE $ git clone https://github.com/tmux-plugins/tpm \\\n   ~/.tmux/plugins/tpm\n## create ~/.tmux.conf if it doesn\'t exist\nbbd025@MACHINE $ test -f ~/.tmux.conf || touch ~/.tmux.conf\n## Add the lines to ~/.tmux.conf as directed by the READMEs. Note that\n##+ that the lines with only a \'.\' allow for spacing between the end of\n##+ anything currently in your ~/.tmux.conf and these lines\nbbd025@MACHINE $ cat <<\'EOF\' | sed \'s/^\\.$//g;\' >> ~/.tmux.conf\n.\n.\n# List of plugins\nset -g @plugin \'tmux-plugins/tpm\'\nset -g @plugin \'tmux-plugins/tmux-sensible\'\n# -v- OUR LOGGING PLUGIN -v-\nset -g @plugin \'tmux-plugins/tmux-logging\'\n\n# Other examples:\n# set -g @plugin \'github_username/plugin_name\'\n# set -g @plugin \'github_username/plugin_name#branch\'\n# set -g @plugin \'git@github.com:user/plugin\'\n# set -g @plugin \'git@bitbucket.com:user/plugin\'\n\n#Initialize TMUX plugin manager(keep this line at the very bottom of tmux.conf)\nrun \'~/.tmux/plugins/tpm/tpm\'\nEOF\nbbd025@MACHINE $\n
Run Code Online (Sandbox Code Playgroud)\n

After getting tmux-logging

\n

Note that if you\'ve used another method to install tmux-logging or configured things differently, you\'ll need to use /my/path/to/tmux-logging/ in place of ~/.tmux/plugins/tmux-logging/.

\n

If you haven\'t already done so, start a tmux session

\n
$ tmux\n
Run Code Online (Sandbox Code Playgroud)\n

You should see a green banner-type thingy on the bottom letting you know you\'re in tmux. Press [Prefix] + Shift + i (also called [Prefix] + I and, by default, Ctrl + b then Shift + i.)

\n

It will show the following lines in the actual terminal, rather than in the green notification bar.

\n
TMUX environment reloaded.\nDone, press ENTER to continue.\n
Run Code Online (Sandbox Code Playgroud)\n

Press ENTER

\n

Now, let\'s edit ~/.tmux/plugins/tmux-logging/scripts/variables.sh.

\n

For what is close to your (the OP\'s) desired outfile name (but which won\'t get overwritten or scrambled when a new window or pane is called up - at least that\'s what I guess would happen), change it so you have the following lines:

\n
# General options\n# Next, commented line has original variable\n#replaced#filename_suffix="#{session_name}-#{window_index}-#{pane_index}-%Y%m%dT%H%M%S.log"\nfilename_suffix="#{session_name}-#{window_index}-#{pane_index}.log"\n
Run Code Online (Sandbox Code Playgroud)\n

(Check out Note [1] to see how I keep this information safe in case of a tmux update.)

\n

You could take out the -#{window_index}-#{pane_index} if you never open multiple windows or panes in your session. That would give a logfile name exactly matching that desired by the OP. If you do end up with multiple panes, I\'m really not sure what would happen with the logging, but I think it would be messed up if not overwritten. FYI, the variables you\'re seeing there are coming from ~/.tmux/plugins/tmux-logging/scripts/shared.sh.

\n

Note that you could also change the default_logging_path a few lines down the file, but this is something that can be taken care of in ~/.tmux.conf, so I didn\'t mess with it.

\n

What I did - where I wanted my username to be part of the logfile, I wanted an absolutely unique and trackable timestamp, and I wanted things sorted chronologically (and where I don\'t like my files going over 80 characters per line) - was to change lines so I had

\n
# General options\n# -v- original before change by bballdave025 -v- , 2022-02-28\n#filename_suffix=\\\n#"#{session_name}-#{window_index}-#{pane_index}-%Y%m%dT%H%M%S.log"\nfilename_suffix="bbd025-%s\\\n-#{session_name}-#{window_index}-#{pane_index}-%Y%m%dT%H%M%S%z.log"\n
Run Code Online (Sandbox Code Playgroud)\n

If you don\'t want something like tmux- before your filename, you should make another change to the variables.sh file. I don\'t do this for my own machine, because there are different filename prefixes for slightly different logging options, but I\'m doing it for this answer.

\n

So, if you don\'t want any prefix, change variables.sh to have the lines:

\n
# original commented out on the line below\n#default_logging_filename="tmux-${filename_suffix}"\ndefault_logging_filename="${filename_suffix}"\n
Run Code Online (Sandbox Code Playgroud)\n

Now, let\'s add what we need to our ~/.tmux.conf. The first line will put output logs into the directory you specified. Any other legitimate path could be placed here. Let\'s make it so that, if you use the tmux-logging screen-capture and/or log-buffer-and-continue-logging options, the screencap or complete-history-with-buffer will be saved in the same directory with your auto-start logfiles. It shouldn\'t matter exactly where in your ~/.tmux.conf file you put these lines, though I keep it before that last line which TMUX Plugin Manager told us to keep at the end.

\n
set -g @logging-path "$HOME/mytmuxsessions"\nset -g @screen-capture-path "$HOME/mytmuxsessions"\nset -g @save-complete-history-path "$HOME/mytmuxsessions"\n
Run Code Online (Sandbox Code Playgroud)\n

Next, we\'ll copy toggle_logging.sh to a new script and make sure it is included in our ~/.bash_profile (or by whatever gets called for sure by non-login scripts.)

\n

I actually source my ~/.bashrc from my ~/.bash_profile with the lines:

\n
# @file  .bash_profile\n\nif [ -f ~/.bashrc ]; then\n  . ~/.bashrc\nfi\n
Run Code Online (Sandbox Code Playgroud)\n

If there are lines such as the following in your ~/.bashrc, you can comment them out.

\n
# If not running interactively, don\'t do anything\n[[ "$-" != *i* ]] && return\n
Run Code Online (Sandbox Code Playgroud)\n

to

\n
## If not running interactively, don\'t do anything\n#[[ "$-" != *i* ]] && return\n
Run Code Online (Sandbox Code Playgroud)\n

Otherwise, if you want to keep your ~/.bashrc for environment and functions ONLY for use in login shells, just add the lines I\'ll put at the end of ~/.bashrc at the end of ~/.bash_login, or whichever file gets loaded for non-login scripts.

\n

Finally, then, we\'re getting to our copy of toggle_logging.sh. Run the copy command given below. Again, I put mine in my home folder (~, a.k.a. $HOME) to make sure it doesn\'t get wiped out by some future tmux upgrade. You can choose a directory and a filename that suits you rather than the ones chosen below.

\n
$ cp ~/.tmux/plugins/tmux-logging/scripts/toggle_logging.sh \\\n     ~/.ensure_tmux_logging_on.sh\n
Run Code Online (Sandbox Code Playgroud)\n

(If you didn\'t use the tpm option for tmux-logging, you\'ll need to get to that script from wherever you cloned or built your tmux-logging.)

\n

Now, make changes to your ~/.ensure_tmux_logging_on.sh so they look like what\'s below. (Note that you don\'t need to keep in the original code that I have commented out. Those parts are there so you can search for the original text and either replace it or comment it out as I have. That way, you\'ll know where the new stuff should go.)

\n

---

\n
### changed for auto-logging (I often put in my username and date of change)\n### bballdave025, 2022-02-28\n#orig#CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"\n\n#orig#source "$CURRENT_DIR/variables.sh"\n#orig#source "$CURRENT_DIR/shared.sh"\n\n## new for tmux auto-logging, bballdave025 2022-02-28\nTMUX_LOGGING_SCRIPTS_DIR="$HOME/.tmux/plugins/tmux-logging/scripts"\nCURRENT_DIR="$TMUX_LOGGING_SCRIPTS_DIR"\n  ## Not really our current dir, but it allows other code called\n  ##+ downstream to work.\n\nsource "$TMUX_LOGGING_SCRIPTS_DIR/variables.sh"\nsource "$TMUX_LOGGING_SCRIPTS_DIR/shared.sh"\n
Run Code Online (Sandbox Code Playgroud)\n

---

\n
### original function commented out, bballdave025 2022-02-28\n#stop_pipe_pane() {\n#  tmux pipe-pane\n#  display_message "Ended logging to $logging_full_filename"\n#}\n\n### new function added, bballdave025 2022-02-28\nconfirm_logging()\n{\n  display_message "Logging already happening to ${logging_full_filename}"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

---

\n
#original comment## starts/stop logging\n# starts/continues logging ( bballdave025, 2022-02-28 )\n#orig#toggle_pipe_pane() {\n## -v- new function name -v- , bballdave025, 2022-03-09\nensure_pipe_pane_on()\n{\n  if is_logging; then\n    #orig#set_logging_variable "not logging"\n    #orig#stop_pipe_pane\n    # -v- bballdave025 2022-02-28 -v- first line probably unneeded (?)\n    set_logging_variable "logging"\n    confirm_logging\n    # everything from here is as in the original\n  else\n    set_logging_variable "logging"\n    start_pipe_pane\n  fi\n}\n\n## -v- main changed -v- by bballdave025, 2022-03-08\n#orig#main() {\n#orig#  if supported_tmux_version_ok; then\n#orig#    toggle_pipe_pane\n#orig#  fi\n#orig#}\n\nmain()\n{\n  if supported_tmux_version_ok; then\n    ensure_pipe_pane_on\n  fi\n}\nmain\n
Run Code Online (Sandbox Code Playgroud)\n

---

\n

You don\'t need to be as verbose as I was, i.e. you don\'t need all the comments and old lines. I\'m hoping to keep things clear as to what is being changed. There are ways to make this code simpler; if you understand what\'s going on, you\'re welcome to do so.

\n

Make sure your script is executable

\n
$ chmod +x ~/.ensure_tmux_logging_on.sh\n
Run Code Online (Sandbox Code Playgroud)\n

Now, we have a few lines to add this to whichever file - ~/.bash_profile, a ~/.bashrc that gets sourced by ~/.bash_profile etc. - that you know will get called for non-login terminals. In my example, I made it so ~/.bashrc got called by `~/.bash_profile for non-login screens, so I\'m going to add my lines there.

\n

Having these lines will make it so ~/.ensure_tmux_logging_on.sh gets run every time we go into a new tmux terminal for the first time. Simply add the following lines just about anywhere in your ~/.bashrc (or other file); I put it towards the end.

\n
if [ ! -z $TMUX ]; then\n  $HOME/.ensure_tmux_logging_on.sh\nfi\n
Run Code Online (Sandbox Code Playgroud)\n
\n

Test it out on my system, `RHEL 8` (RedHat based).

\n

Short version: it works. You can skip all this next part, though I do suggest looking at the 5 items just below.

\n

The important things to know are these:

\n

1) Now, running the OP\'s commands, i.e.

\n
$ tmux new -s mysession1\n
Run Code Online (Sandbox Code Playgroud)\n

leads to the logfile,

\n

~/mytmuxsessions/mysession1-1-1.log

\n

And similary, $ tmux new -s mysession2 leads to the logfile, ~/mytmuxsessions/mysession2-1-1.log

\n

2) Any newly-created windows/panes in these sessions will be denoted by numbers, even if you create them with names using commands at the terminal prompt.

\n

3) If you don\'t provide a name for the session (which providing of a name can only be done by starting a new window from the terminal prompt and using the ( \xc2\xa0 -s \xc2\xa0 ) SESSION_NAME` option, you will only get the assigned session number.

\n

4) As things are set up for the OP, a log for any new session having the same name as one created before, e.g. a second use of tmux new -s mysession1 will overwrite the previous logfile. That doesn\'t feel very clear without an example, so here is one.

\n
$ ls -lAh ~/mytmuxsessions # to see that mysession1-1-1.log is already there\n-rw-r--r--. 1 bbd025 bbd025 405 Mar   1  10:22 mysession1-1-1.log\n-rw-r--r--. 1 bbd025 bbd025 824 Feb   28 17:40 mysession2-1-1.log\n$ tmux new -s mysession1 # I\'ll enter a new tmux session after this command\n(tmux)$ # Some stuff.\n(tmux)$ echo "Putting text, I/O, etc. in the logfile"\n(tmux)$ alias ls=\'ls --color=auto\'\n(tmux)$ type ls\nls is aliased to \'ls --color=auto\'\n(tmux)$ tmux kill-session -t mysession1\n$ ls -lAh ~/mytmuxsessions\n-rw-r--r--. 1 bbd025 bbd025 1.6K Mar   2  13:02 mysession1-1-1.log\n-rw-r--r--. 1 bbd025 bbd025 824  Feb   28 11:40 mysession2-1-1.log\n
Run Code Online (Sandbox Code Playgroud)\n

The first logfile, mytmuxsession1-1-1.log, created Mar 1 10:22, and having a size of 405 bytes no longer exists. Instead, we now have mytmuxsession1-1-1.log, created Mar 2 13:02, and having a size of 1.6K.

\n

If you want to avoid this overwriting, just include some type of date string, in the format of the BSD date command, e.g. change your tmux-logging\'s variables.sh to have something like

\n
filename_suffix="#{session_name}-#{window_index}-#{pane_index}\\\n-%Y%m%dT%H%M%S%z.log"\n
Run Code Online (Sandbox Code Playgroud)\n

Note that this is different from the overwriting during a tmux session that I discussed before.

\n

5) I\'m not sure if this is actually necessary, but I added the following to my ~/.bashrc (or ~/.bash_profile or whatever). There is a version with more comments/options further down in the example.

\n
## Function to be run every time one exits a bash terminal\nfinish()\n{\n  if [ ! -z $TMUX  ]; then\n    $HOME/.tmux/plugins/tmux-logging/scripts/toggle_logging.sh\n  fi\n}\n\ntrap finish EXIT\n
Run Code Online (Sandbox Code Playgroud)\n

Short Example

\n

Before you test things out, you should exit and restart your terminal, or run source ~/.bashrc (or source whichever similar file you edited). I prefer the second method, but if you\'re not sure about the ~/.bash_profile, ~/bashrc, etc. stuff, it might be best for you just to restart.

\n

Edit I had a longer example which felt even more like overkill than this answer already did. If you really want to see it, I\'ve taken screenshots which will be attached. For now, the pages - p1, p2, and p3 - now all point to www.google.com. p1, p2, and p3.

\n

Instead of the long example, I\'m just going to show a sequence of commands. For my real logs, I ran a few commands and made a few comments after getting into a new tmux session, window, or pane. At the end, I\'ll show the resultant files.

\n

I should be a bit more specific about my system. I\'ve got an SSH connection through PuTTY to a RHEL8 machine, which gives me a main terminal. From there, I run

\n
$ tmux new -s mysession1\n
Run Code Online (Sandbox Code Playgroud)\n

(This will bring up session: