Shell-Script

有沒有辦法將所有 shell 腳本輸出發送到終端和日誌文件,加上使用者輸入的任何文本?

  • September 30, 2021

我想將 shell 腳本的輸出(包括使用者輸入的文本)發送到終端和日誌文件。

我認為一些組合可能會做到這一點teeexec但到目前為止我還沒有運氣。我知道tee它本身可以回顯並擷取使用者在終端中輸入的內容:

$ tee logfile
Hello  (I entered this at runtime)
Hello  (I entered this at runtime)
^C

$ cat logfile
Hello  (I entered this at runtime)

但我需要查看(在終端和日誌文件中)使用者輸入的內容以響應在 shell 腳本中呼叫的命令。

tee似乎無法始終如一地做到這一點。

例如:

$ read message 2>&1 | tee logfile
Hello  (I entered this at runtime)

$ cat logfile

那裡什麼也沒拍到。我希望Hello (I entered this at runtime)像以前一樣在文件中看到。

我還嘗試在 shell 腳本中結合teewith ,如下所示:exec

$ cat test.bash
#!bin/bash
# Note: in this simplified version of this file, I’m not looking at $1, $2, or anything else passed in, but will need to eventually

rm -f logfile
exec &> >(tee -a logfile)
echo “Say \”Hello\”” 2>&1
read -p “> “ 2>&1

不幸的是,添加exec沒有幫助:

$ ./test.bash
Say “Hello”
> Hello  (I entered this at runtime)

$ cat logfile
Say “Hello”
> 

如您所見,它擷取了echo命令和read命令的輸出,但沒有擷取我為響應read命令而輸入到終端的內容。

有沒有辦法做到這一點?

我知道script命令(“製作終端會話的打字稿”)可以擷取螢幕上的所有內容並將其放入日誌文件中。但是script無法從 shell 腳本中以有用的方式呼叫該命令。(它可以?)

script需要首先呼叫,然後使用者必須呼叫所需的 shell 腳本。但我希望使用者只需呼叫一個命令及其參數,然後讓該命令負責執行其他所有內容並記錄所有內容。

然後是腳本擷取的所有“額外”資訊(例如顏色程式碼、退格),這使得在任意文本編輯器中讀取生成的日誌文件變得很困難。

我只想查看日誌文件中的“人類可讀”字元。而且我不想查看使用者是否更正了拼寫錯誤。我只想看到他們完成編輯並按 Enter 後螢幕上顯示“Hello”。雖然我認為額外的資訊可以在捕穫後被剝離。

至少的script實現是可編寫腳本的。util-linux

例如,您可以這樣做:

SHELL=/bin/sh script -qec '
 # any sh code here
 echo Whatever
 cat # user input' file.log

並將file.log擷取寫入終端的所有內容,包括您鍵入的內容的*迴聲。*這還包括由 tty 行規程執行的轉換,例如將 LF 轉換為 CRLF。

script還增加了一些

Script started on 2021-09-29 14:58:59+01:00 [TERM="screen.xterm-256color" TTY="/dev/pts/8" COLUMNS="191" LINES="54"]

標題和:

Script done on 2021-09-29 14:58:59+01:00 [COMMAND_EXIT_CODE="0"]

從具有 ksh 樣式程序替換支持的 shell 中的頁腳,您可以使用以下命令刪除:

SHELL=/bin/sh script -qec '...' >(sed '1d;$d' > file.log)

或者,正如@zevzek 所建議的那樣,告訴script將包含頁眉/頁腳的日誌寫入/dev/null,但將script的輸出(-q沒有頁眉或頁腳)重定向tee到進行日誌記錄。

(set -o pipefail; SHELL=/bin/sh script -qec '...' /dev/null | tee file.log)

或 with zshon multi_ios(預設情況下):

SHELL=/bin/sh script -qec '...' /dev/null >&1 > file.log

要禁用由 開始的偽 tty 的 tty 行規程的輸出後處理script,您可以在此處禁用它並至少在主機 tty 上重新啟用 NL -> CRNL 轉換,如下所示:

SHELL=/bin/sh HOST_TTY="$(tty)" script -qec '
 stty -opost && stty < "$HOST_TTY" opost onlcr || exit
 ...' file.log

(假設中的命令...不恢復該輸出處理)。

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