Logs

如何根據我的會話名稱自動將我的所有“tmux”會話記錄到目錄中的文件中?

  • March 10, 2022

我有幾個命名tmux會話。例如:

$ tmux new -s mysession1
$ tmux new -s mysession2

我想在我的里面放一些東西,~/.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

但我想要的是相當於Linux scriptcommand的東西,我可以根據我的會話名稱script -f mysession.log將其放入我的終端輸出中,以不斷將我的終端輸出保存到日誌文件中。~/.tmux.conf

我無法找到一種方法來動態設置日誌文件的完整文件路徑.tmux.conf。就動態而言,我的意思是根據您的情況下的會話名稱,在我的情況下根據Unix 時間戳。但是,我能夠使用tmux-logging的基本程式碼;我修改了原始碼以獲得適合我的東西。

請注意,此解決方案不會將特定會話中的所有內容保存在一個日誌文件中。這是可以做到的,但是將可能存在於此類會話中的不同視窗和窗格組合起來會很困難。但是,此解決方案將為會話中的每個窗格保存一個日誌文件,因此日誌文件中將包含您的所有輸入和輸出。您總是可以從 中派生tmux-plugins/tmux-login,或者您可以根據他們放在一起的內容編寫自己的程式碼,並且只使用您喜歡的內容。


TL;博士

tmux-loggingtmux-pluginsgit 儲存庫安裝。

更改變數定義filename_suffix以匹配您想要的格式。這應該在/path/to/tmux-plugins/tmux-logging/scripts/variables.sh.

將其複製toggle_logging.sh到另一個腳本 - 我稱之為它~/.ensure_tmux_logging_on.sh,它在我的$HOME目錄中,因此未來的更新tmux不會將其清除。更改腳本,使其if is_logging不執行任何操作(或僅輸出消息)。保持關聯的else分支不變。

~/.ensure_tmux_logging_on.sh從您的.bash_profile(或.bash_login.login.profile- 以確保它被非登錄 shell 呼叫)呼叫您的。tmux總是打開一個非登錄 shell,所以.bashrc除非你從以前的腳本之一中獲取它,否則它不會工作。請參閱此處 (1)此處 (2)此處 (3) - 所有三個都是對同一個 AskUbuntu 問題的答案 - 了解更多詳細資訊。

將筆記記在某處,因為如果有更新tmux-logging,您將不得不使用相同的 hack。

我試圖想辦法.tmux.conf用*.* .tmux.conf


更多細節

我使用Tmux Plugin Manager ( tpm) 方法進行安裝tmux-logging,這意味著我一次安裝tpmtmux-loggingtpm下面是一些快速命令,它們執行和的自述文件中描述的內容tmux-logging請注意,如果您已經擁有,請按照自述文件中tpm說明進行操作,即添加該行tmux-logging

set -g @plugin 'tmux-plugins/tmux-logging'

到您的外掛列表中~/.tmux.conf

tpm您可以使用此命令查看您是否擁有(至少是標準安裝)

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

如果沒有tpm,請執行

#(prompt can be in tmux or not)
## It's best, but not necessary, to get in the directory where we'll be doing stuff.
bbd025@MACHINE $ cd
## check the existence of ~/.tmux/plugins/tpm directory, 
##+ create it if it doesn't exist
bbd025@MACHINE $ test -d ~/.tmux/plugins/tpm || mkdir -p ~/.tmux/plugins/tpm
## clone in the tpm code
bbd025@MACHINE $ git clone https://github.com/tmux-plugins/tpm \
  ~/.tmux/plugins/tpm
## create ~/.tmux.conf if it doesn't exist
bbd025@MACHINE $ test -f ~/.tmux.conf || touch ~/.tmux.conf
## Add the lines to ~/.tmux.conf as directed by the READMEs. Note that
##+ that the lines with only a '.' allow for spacing between the end of
##+ anything currently in your ~/.tmux.conf and these lines
bbd025@MACHINE $ cat <<'EOF' | sed 's/^\.$//g;' >> ~/.tmux.conf
.
.
# List of plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
# -v- OUR LOGGING PLUGIN -v-
set -g @plugin 'tmux-plugins/tmux-logging'

# Other examples:
# set -g @plugin 'github_username/plugin_name'
# set -g @plugin 'github_username/plugin_name#branch'
# set -g @plugin 'git@github.com:user/plugin'
# set -g @plugin 'git@bitbucket.com:user/plugin'

#Initialize TMUX plugin manager(keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
EOF
bbd025@MACHINE $

獲得 tmux-logging 之後

請注意,如果您使用其他方法來安裝或配置不同的東西,則tmux-logging需要使用/my/path/to/tmux-logging/.~/.tmux/plugins/tmux-logging/

如果您還沒有這樣做,請開始一個tmux會話

$ tmux

您應該在底部看到一個綠色橫幅類型的東西,讓您知道您在tmux. 按+ + (也稱為+和預設情況下+然後+ 。)$$ Prefix $$``Shift``i``$$ Prefix $$``I``Ctrl``b``Shift``i

它將在實際終端中顯示以下行,而不是在綠色通知欄中。

TMUX environment reloaded.
Done, press ENTER to continue.

ENTER

現在,讓我們編輯~/.tmux/plugins/tmux-logging/scripts/variables.sh.

對於與您(OP)所需的輸出文件名稱相近的內容(但在呼叫新視窗或窗格時不會被覆蓋或打亂 - 至少我猜會發生這種情況),請更改它,以便您擁有以下內容行:

# General options
# Next, commented line has original variable
#replaced#filename_suffix="#{session_name}-#{window_index}-#{pane_index}-%Y%m%dT%H%M%S.log"
filename_suffix="#{session_name}-#{window_index}-#{pane_index}.log"

(查看備註$$ 1 $$看看我如何在tmux更新時保護這些資訊的安全。)

-#{window_index}-#{pane_index}如果您從未在會話中打開多個視窗或窗格,則可以刪除。這將給出一個與 OP 所需的完全匹配的日誌文件名稱。如果你最終有多個窗格,我真的不確定日誌記錄會發生什麼,但我認為如果不覆蓋它會搞砸。僅供參考,您看到的變數來自~/.tmux/plugins/tmux-logging/scripts/shared.sh.

請注意,您也可以更改default_logging_path文件中的幾行,但這是可以在 中處理的~/.tmux.conf,所以我沒有弄亂它。

我所做的——我希望我的使用者名成為日誌文件的一部分,我想要一個絕對唯一且可跟踪的時間戳,我想要按時間順序排序的事情(而且我不喜歡我的文件每行超過 80 個字元)——是換線所以我有

# General options
# -v- original before change by bballdave025 -v- , 2022-02-28
#filename_suffix=\
#"#{session_name}-#{window_index}-#{pane_index}-%Y%m%dT%H%M%S.log"
filename_suffix="bbd025-%s\
-#{session_name}-#{window_index}-#{pane_index}-%Y%m%dT%H%M%S%z.log"

如果你不想tmux-在你的文件名之前出現類似的東西,你應該對variables.sh文件進行另一次更改。我不會為我自己的機器這樣做,因為對於稍微不同的日誌記錄選項有不同的文件名前綴,但我這樣做是為了這個答案。

因此,如果您不想要任何前綴,請更改variables.sh為具有以下行:

# original commented out on the line below
#default_logging_filename="tmux-${filename_suffix}"
default_logging_filename="${filename_suffix}"

現在,讓我們將我們需要的內容添加到我們的~/.tmux.conf. 第一行會將輸出日誌放入您指定的目錄中。任何其他合法路徑都可以放在這裡。讓我們這樣做,如果您使用tmux-logging螢幕擷取和/或日誌緩衝區和繼續記錄選項,則螢幕截圖或完整歷史記錄與緩衝區將與您的自動啟動日誌文件一起保存在同一目錄中. 將這些行放在文件中的確切位置並不重要~/.tmux.conf,儘管我將它保留在 TMUX 外掛管理器告訴我們最後保留的最後一行之前。

set -g @logging-path "$HOME/mytmuxsessions"
set -g @screen-capture-path "$HOME/mytmuxsessions"
set -g @save-complete-history-path "$HOME/mytmuxsessions"

接下來,我們將復製toggle_logging.sh到一個新腳本並確保它包含在我們的~/.bash_profile(或由非登錄腳本確定呼叫的任何內容中。)

我實際上是~/.bashrc從我~/.bash_profile的行中獲取我的:

# @file  .bash_profile

if [ -f ~/.bashrc ]; then
 . ~/.bashrc
fi

如果您的 中存在如下行~/.bashrc,您可以將其註釋掉。

# If not running interactively, don't do anything
[[ "$-" != *i* ]] && return

## If not running interactively, don't do anything
#[[ "$-" != *i* ]] && return

否則,如果您想讓您的~/.bashrcfor 環境和函式僅在登錄 shell 中使用,只需添加我將放在~/.bashrc末尾的行~/.bash_login,或者為非登錄腳本載入的任何文件。

最後,然後,我們將獲得toggle_logging.sh. 執行下面給出的複制命令。再一次,我把我的放在我的主文件夾(~aka $HOME)中,以確保它不會被未來的tmux升級清除掉。您可以選擇適合您的目錄和文件名,而不是下面選擇的。

$ cp ~/.tmux/plugins/tmux-logging/scripts/toggle_logging.sh \
    ~/.ensure_tmux_logging_on.sh

(如果您沒有使用 的tpm選項tmux-logging,則需要從複製或建構的任何位置訪問該腳本tmux-logging。)

現在,對您的進行更改,使其~/.ensure_tmux_logging_on.sh看起來如下所示。(請注意,您不需要保留我已註釋掉的原始程式碼。這些部分在那裡,因此您可以搜尋原始文本並替換它或像我一樣將其註釋掉。這樣,您將知道新東西應該去哪裡。)

---

### changed for auto-logging (I often put in my username and date of change)
### bballdave025, 2022-02-28
#orig#CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

#orig#source "$CURRENT_DIR/variables.sh"
#orig#source "$CURRENT_DIR/shared.sh"

## new for tmux auto-logging, bballdave025 2022-02-28
TMUX_LOGGING_SCRIPTS_DIR="$HOME/.tmux/plugins/tmux-logging/scripts"
CURRENT_DIR="$TMUX_LOGGING_SCRIPTS_DIR"
 ## Not really our current dir, but it allows other code called
 ##+ downstream to work.

source "$TMUX_LOGGING_SCRIPTS_DIR/variables.sh"
source "$TMUX_LOGGING_SCRIPTS_DIR/shared.sh"

---

### original function commented out, bballdave025 2022-02-28
#stop_pipe_pane() {
#  tmux pipe-pane
#  display_message "Ended logging to $logging_full_filename"
#}

### new function added, bballdave025 2022-02-28
confirm_logging()
{
 display_message "Logging already happening to ${logging_full_filename}"
}

---

#original comment## starts/stop logging
# starts/continues logging ( bballdave025, 2022-02-28 )
#orig#toggle_pipe_pane() {
## -v- new function name -v- , bballdave025, 2022-03-09
ensure_pipe_pane_on()
{
 if is_logging; then
   #orig#set_logging_variable "not logging"
   #orig#stop_pipe_pane
   # -v- bballdave025 2022-02-28 -v- first line probably unneeded (?)
   set_logging_variable "logging"
   confirm_logging
   # everything from here is as in the original
 else
   set_logging_variable "logging"
   start_pipe_pane
 fi
}

## -v- main changed -v- by bballdave025, 2022-03-08
#orig#main() {
#orig#  if supported_tmux_version_ok; then
#orig#    toggle_pipe_pane
#orig#  fi
#orig#}

main()
{
 if supported_tmux_version_ok; then
   ensure_pipe_pane_on
 fi
}
main

---

你不需要像我一樣冗長,即你不需要所有的評論和舊行。我希望清楚地了解正在發生的變化。有一些方法可以使這段程式碼更簡單;如果您了解發生了什麼,歡迎您這樣做。

確保您的腳本是可執行的

$ chmod +x ~/.ensure_tmux_logging_on.sh

現在,我們有幾行程式碼可以將它添加到任何文件中 - ~/.bash_profile,一個~/.bashrc由等來源的文件 -~/.bash_profile你知道將被非登錄終端呼叫。在我的範例中,我讓它~/.bashrc被 `~/.bash_profile 呼叫以用於非登錄螢幕,所以我將在那裡添加我的行。

擁有這些行將使它在~/.ensure_tmux_logging_on.sh我們第一次進入新tmux終端時執行。只需在您~/.bashrc(或其他文件)中的任何位置添加以下行;我把它放在最後。

if [ ! -z $TMUX ]; then
 $HOME/.ensure_tmux_logging_on.sh
fi

在我的系統“RHEL 8”(基於 RedHat)上進行測試。

簡短版本:它有效。您可以跳過下一部分的所有內容,但我建議您查看下面的 5 個項目。

需要了解的重要事項如下:

**1)**現在,執行OP的命令,即

$ tmux new -s mysession1

導致日誌文件,

~/mytmuxsessions/mysession1-1-1.log

同樣,$ tmux new -s mysession2導致日誌文件,~/mytmuxsessions/mysession2-1-1.log

**2)**這些會話中的任何新創建的視窗/窗格都將用數字表示,即使您使用終端提示符下的命令創建它們的名稱也是如此。

**3)**如果您沒有為會話提供名稱(提供名稱只能通過從終端提示符啟動新視窗並使用 (   -s   ) SESSION_NAME` 選項來完成,您將只能獲得分配的會話編號。

**4)**隨著 OP 的設置,任何與之前創建的具有相同名稱的新會話的日誌,例如第二次使用tmux new -s mysession1將覆蓋以前的日誌文件。沒有例子就感覺不太清楚,所以這裡有一個。

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

第一個日誌文件 、mytmuxsession1-1-1.logcreatedMar 1 10:22405字節大小不再存在。相反,我們現在有mytmuxsession1-1-1.log、 createdMar 2 13:02和大小為1.6K.

如果您想避免這種覆蓋,只需以 BSDdate命令的格式包含某種類型的日期字元串,例如將您的 tmux-logging 更改variables.sh為類似

filename_suffix="#{session_name}-#{window_index}-#{pane_index}\
-%Y%m%dT%H%M%S%z.log"

請注意,這與我之前討論的會話期間的覆蓋不同。tmux

**5)**我不確定這是否真的有必要,但我在我的~/.bashrc~/.bash_profile或其他)中添加了以下內容。範例中有一個帶有更多註釋/選項的版本。

## Function to be run every time one exits a bash terminal
finish()
{
 if [ ! -z $TMUX  ]; then
   $HOME/.tmux/plugins/tmux-logging/scripts/toggle_logging.sh
 fi
}

trap finish EXIT

短的 例子

在測試之前,您應該退出並重新啟動終端,或執行source ~/.bashrc(或獲取您編輯的任何類似文件)。我更喜歡第二種方法,但如果您不確定~/.bash_profile,~/bashrc等內容,最好重新啟動。

編輯我有一個更長的例子,感覺比這個答案已經做的更像是矯枉過正。如果你真的想看,我已經截取了截圖,將附上。目前,頁面 p1、p2 和 p3 現在都指向www.google.comp1p2p3

我將展示一系列命令,而不是冗長的範例。對於我的真實日誌,我在進入新tmux會話、視窗或窗格後執行了一些命令並發表了一些評論。最後,我將展示生成的文件。

我應該更具體地了解我的系統。我通過 PuTTY 與 RHEL8 機器建立了 SSH 連接,這給了我一個主終端。從那裡,我跑

$ tmux new -s mysession1

(這將打開 session: mysession1; window: 1; 和 pane: 1。它還將啟動日誌文件mysession1-1-1.log。)

在做了一些評論並按下+之後,這就是終端的樣子。$$ Prefix $$``$$ w $$``tmux

┌──────────────────────────────────────────────────────────────────────────────┐
│(0)  - mysession1: 1 windows (attached)                                       │
│(1)  └─> 1 bash* (1 panes) "bbd025@MACHINE: /home/bbd025"                     ┆
│
│
│┌ 1 (sort: index)────────────────────────────────────────────────────────────┐┆
││ bbd025@MACHINE:~                                                           ││
││ $ # I'm in tmux, and it looks like it's logging!                           ││
││ bbd025@MACHINE:~                                                           ││
││ $ # I'll press [Prefix]+[w] to see session info & then [ENTER] to get back ││
││ bbd025@MACHINE:~                                                           ││
││                                 ┌───┐                                      ││
││                                 │ 1 │                                      ││
││                                 └───┘                                      ││
│└────────────────────────────────────────────────────────────────────────────┘│
│[mysession1:bash*                  "bbd025@MACHINE: /home/bbd" HH:MM dd-mmm-yy│
└──────────────────────────────────────────────────────────────────────────────┘

$$ Prefix $$+w提出了您在上面看到的內容。要返回會話,請確保它已突出顯示(這是唯一的會話,因此您無需執行任何操作),然後按ENTER

讓我們分離會話並開始使用mysession2. 對不起,我從命令行搞砸了,但我希望日誌文件的大小正確

$ tmux detach-client -s mysession1

現在,我們回到了非 tmux shell。雖然我展示了一個不同的程式碼塊,但它會替換終端上的內容,同時仍位於相同的終端位置。

$ tmux new -s mysession2

出現的tmux終端將有日誌文件mysession2-1-1.log

此時,使用+調出$$ Prefix $$``w

(0)  - mysession1: 1 windows
(1)  └─> 1: bash* (1 panes) "bbd025@MACHINE: /home/bbd025"
(2)  - mysession2: 1 windows (attached)
(3)  └─> 1: bash* (1 panes) "bbd025@MACHINE: /home/bbd025"
$ tmux detach-client -s mysession2

將我們帶回到非 tmux shell,我們可以在其中殺死mysession2.

$ tmux kill-session -t mysession2

讓我們嘗試在 中打開另一個視窗mysession1,然後從第二個視窗打開一個單獨的窗格,看看日誌是如何結束的。從非 tmux 終端開始。

tmux attach -t mysession1

您將看到已在原始tmux new -s mysession1窗格中鍵入的任何內容。

$ tmux new-window -n second_window

出現了一個新的空白tmux bash終端。這將有 logfile mysession1-2-1.log

$ tmux ls
mysession1: 2 windows (Created Mon Feb  28 12:02:06 2022) [80x29] (attached)
$ # I press [Prefix]+[n] to get to the next `tmux` window, i.e. the one with
$ #+ logfile, `mysession1-1-1.log`
$ tmux split-window -v # This is the same as [Prefix]+[%]

現在有兩個終端 - 由一行破折號分隔 - 一個在另一個之上。底部終端有日誌文件mysession1.1.2

$ tmux display-panes
$ # You'll have seen numbers on each pane. The bottom one should have
$ #+ shown '2'. If you want to make sure you are typing in pane 2, do
$ tmux select-pane -t 2
$ # You could also have done [Prefix]+[q]+[2]

在窗格 2 中,讓我們打開一個沒有名稱的新視窗。

$ tmux new -w

您現在位於帶有 logfile 的 tmux 終端中0-1-1

現在,在 之後tmux kill-server,讓我們對日誌文件進行最後檢查。

# In T0
$ ls -Ss1pq --block-size=1
total 28672
12288 mysession1-1-1.log
4096 0-1-1.log
4096 mysession1-1-2.log
4096 mysession2-1-1.log
4096 mysession1-2-1.log
$ ls -lAh
total 28K
-rw-r--r--. 1 bbd025 bbd025 1.3K Mar  8 12:03 0-1-1.log
-rw-r--r--. 1 bbd025 bbd025 8.5K Mar  8 11:49 mysession1-1-1.log
-rw-r--r--. 1 bbd025 bbd025  767 Mar  8 11:49 mysession1-1-2.log
-rw-r--r--. 1 bbd025 bbd025  648 Mar  8 11:49 mysession1-2-1.log
-rw-r--r--. 1 bbd025 bbd025  725 Mar  7 17:41 mysession2-1-1.log

筆記:

$$ 1 $$我們的新filename_suffix變數可能無法在tmux更新後繼續存在。為了讓我可以記住並訪問更改,我會(在 OP 的情況下)將以下內容添加到我的~/.bash_profile

export MY_TMUX_FNAME_SUFFIX_LINE='filename_suffix="#{session_name}-#{window_index}-#{pane_index}.log"'

對於我的情況,我將添加以下內容。我跳過了每行 80 個字元的規則,以使事情變得更簡單。

export MY_TMUX_FNAME_SUFFIX_LINE='filename_suffix="bbd025-%s-#{session_name}-#{window_index}-#{pane_index}-%Y%m%dT%H%M%S%z.log"'

現在,你基本上有一個環境變數 - 可見

echo $MY_TMUX_FNAME_SUFFIX_LINE

您可以在以後的tmux更新後回顧它,這樣您就知道如何保留您為日誌文件名稱所做的個性化設置。

引用自:https://unix.stackexchange.com/questions/623054