シェルスクリプトの出力(ユーザーが入力したテキストを含む)を端末とログファイルに送信したいと思います。
tee
私はとの任意の組み合わせがトリックを行うことができると思いますexec
が、これまで運はありませんでした。tee
ユーザーが端末に入力した内容を自分でエコーしてキャプチャできることがわかります。
$ tee logfile
Hello (I entered this at runtime)
Hello (I entered this at runtime)
^C
$ cat logfile
Hello (I entered this at runtime)
ただし、シェルスクリプトで呼び出されたコマンドに応答して、ユーザーが入力した内容を端末とログファイルの両方で確認する必要があります。
tee
絶えずできないようです。
例えば:
$ read message 2>&1 | tee logfile
Hello (I entered this at runtime)
$ cat logfile
そこには何も捉えられませんでした。Hello (I entered this at runtime)
以前のようにファイルとして見ることができたらと思います。
また、次のようなシェルスクリプトにまとめてみましたtee
。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
コマンド("make typescript of Terminal session")が画面上のすべてをキャプチャしてログファイルに保存することを知っています。ただし、script
コマンドはシェルスクリプトで便利な方法で呼び出すことはできません。 (できますか?)
script
まず呼び出す必要があり、次にユーザーは必要なシェルスクリプトを呼び出す必要があります。しかし、私はユーザーがコマンドとその引数を呼び出し、そのコマンドが他のすべてを実行し、すべてを記録するようにしたいと思います。
これにより、スクリプトがキャプチャしたすべての「追加」情報(カラーコード、バックスペースキーなど)があるため、テキストエディタで結果ログファイルを読み取ることが困難になります。
ログファイルで「人が読める」文字を見たいです。ユーザーがスペルエラーを修正したことを確認したくありません。編集を終えてEnterキーを押したときに「Hello」が画面に表示されるのを見たいです。キャプチャ後に追加情報が削除される可能性があると思います。
答え1
script
少なくとも実装はutil-linux
スクリプト可能です。
たとえば、次のようにできます。
SHELL=/bin/sh script -qec '
# any sh code here
echo Whatever
cat # user input' file.log
file.log
以下を含む端末に記録されているすべての内容をキャプチャします。エコあなたが入力したもの。これには、LF から CRLF への変換などの tty 行規則によって実行される変換も含まれます。
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=/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)
zsh
またはonを使用して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
(のコマンドが...
この出力処理を復元しないとします。)
答え2
アプリケーションがttyデバイスに読み書きする内容を記録するもう1つの方法は、strace -P "$(tty)"
ttyへのすべてのシステムコールを記録し、読み取りと書き込みの16進ダンプを含めることです。その後、xxdを使用してデコードできます。
strace -f -e read=all -e write=all \
-e trace='read,write' \
-P "$(tty)" \
-e status=successful -o '|
grep "^ "|cut -b11-60 | xxd -p -r > file.log
' -qqs0 -a0 cat
答え3
使用tee
この構文を使用してください。
read message
echo "${message}" | tee file
file
あなたのコメントが完了するまで、あなたのコメントがそこにあることを保証できます。