
gnome ターミナルでコマンドを実行したところ、予想よりも多くの出力がターミナルに表示されました。出力全体を読みたいのですが、ターミナルのスクロールは先頭に到達する前に停止します。
ターミナルプロファイル設定を変更して無制限のスクロールを有効にしたり、出力をファイルにパイプしたりできることは理解しています。これらの一般的な解決策はすべて、未来ただし、出力は。
すでに実行されたコマンドの完全なターミナル出力を表示するにはどうすればよいですか?
編集: わかりました、それはできません。皆さん、ありがとう!
答え1
私の経験では、コメントの合意は正しいです。端末のバッファを超えると、そのデータは失われます (または、まだ上書きされていないメモリ内にある可能性もあります)。そのため、バッファ サイズを遡及的に増やすことはできません。
この回答は、コメントと回答の境界線上であり、状況によってはやり過ぎかもしれません。これはむしろ、状況に対応できる提案されたアプローチです。特に、ログが必要であることに気付いたときには手遅れになっているという問題 (因果関係のない問題は難しい) に対処するものですが、質問への直接的な回答ではありません。
いずれにせよ、コメントするには長すぎました。このアプローチを実装するために必要なすべてのコードを明示的にリストしているわけではありません。主な理由は、実装に関して決定しなければならないことがたくさんあるためです。より詳細な情報が必要な場合は、喜んで提供させていただきます。
Script
対処するのは決して楽しいことではない
まず、このscript
ユーティリティは、バッファ サイズを増やさずにデータの損失を防ぐための「一時しのぎ」として提案されています (バッファ サイズを無制限に設定するとセキュリティに影響します)。TLC を必要とするユーティリティがあるとすれば、それscript
はこれです。ただし、これはカーネル チームによって開発されたものです。ご自由に解釈してください。
私は、script
その価値よりも面倒なことが多いと感じています (後処理して、人間が半分読めるようにするなど)。そのため、代わりに、stdout、stdin、および/または stderr をログに記録する簡略化された方法を使用するようになりました。ある意味では、これはスクリプトを再作成することですが、ハードコードされたscript
ログ設定に左右されるのではなく、完全に制御できます。
このアプローチは、比較的シームレスにシェル セッションに統合できます。また、まれに端末バッファがオーバーフローした場合でも、その内容を含む一時ファイルが作成されます。ログを「クリーン」に保つには、対処する必要があるいくつかのハウスキーピング手順があります。さらに、同じセキュリティ問題 (すべての端末出力のログ) がデフォルトで存在しますが、ログを暗号化する簡単な方法があります。
基本的な手順は 3 つあります。
- stdout (および必要に応じて stderr) をファイルとターミナルに分割するようにリダイレクトを構成します。この例はシンプルにし、stdin または stderr をファイルにリダイレクトしていませんが、stdout リダイレクトの例を理解していれば、残りは簡単です。
- シェルが開かれるたびにこのログ記録が開始されるように .bashrc を構成します。
- 特定のシェルが閉じるときに、bash 組み込みを使用して
TRAP
ユーザー コードを呼び出し、セッション ログを終了します (ファイルを削除したり、アーカイブしたりできます)。
このアプローチにより、実質的に目に見えないセーフティ ネットが実現し、特定のシェル セッションの履歴全体を確認できます (リダイレクトする内容に基づきます。ここでも、簡略化のため stdout のみを表示しています)。必要がない場合は、その存在すら認識しないはずです。
詳細
1. リダイレクトを構成する
次のコード スニペットは、ログ ファイルを指すファイル記述子 3 を作成します。stdout は 3 にリダイレクトされ、 を使用してtee
、そのストリームをターミナル (stdout と同等) に分割します。同じコマンド/ログ ファイルに stderr を簡単に追加したり、別のファイルにパイプしたり、そのまま (ログに記録せずに) 残したりできます。
logFile=$(mktemp -u)
exec 3>&1 1> >(tee $logFile >&3)
このログ ファイルは、スクリプトによって生成されるログ ファイルよりもはるかにクリーンであることがわかります。バックスペース、改行、その他の不要な特殊文字は保存されません。
ログファイルを暗号化したい場合は、teeコマンドの後にパイプステージを追加することで簡単に行うことができます。オープンSSL。
2. ログ生成を自動化する
.bashrc に上記と同じコードを追加します。新しいシェルが作成されるたびに、そのセッションに固有のログ ファイルが作成されます。
export logFile=$(mktemp -u)
exec 3>&1 1> >(tee $logFile >&3)
echo "Current session is being logged in $logFile"
3. シェルが閉じるときに自動的にログを閉じる
セッションが終了したときにログ ファイルを削除する場合は、bash 組み込みtrap
関数を使用してセッションの終了を検出し、たとえばログ ファイルを指定する関数を呼び出します (.bashrc 内も同様)。
trap closeLog EXIT
closeLog () {
rm -f "$logFile" >/dev/null 2>&1
}
セッション ログのクリーンアップは、さまざまな方法で処理できます。このアプローチは、シェルが 'exit' シグナルをトラップして閉じるときに呼び出されます。この時点で、ログ ファイルを削除したり、移動したり、名前を変更したり、さまざまな方法でクリーンアップできます。また、ログ ファイルを TRAP 経由ではなく cron ジョブでクリーンアップすることもできます (このアプローチを使用する場合、/tmp ディレクトリにクリーンアップ タスクがまだ構成されていない場合は、定期的なクリーンアップ タスクをお勧めします。bash シェルがクラッシュすると、EXIT トラップがトリガーされません)。
サブシェルの取り扱いに関する注意
サブシェルでは興味深い状況が発生します。既存のシェルの上に新しい対話型シェルが開かれると、新しいログが作成され、すべて正常に動作するはずです。そのシェルが終了すると (親に戻ると)、そのファイルへのログ記録が再開されます。これをよりきれいに解決したい場合 (対話型またはそれ以外のサブシェルの共通ログを維持するなど)、ネストされたサブシェル内にいることを検出し (.bashrc で)、新しいログ ファイルを作成するのではなく、親のログ ファイルにリダイレクトする必要があります。また、終了時に 'trap' 呼び出しによって親のログ ファイルが削除されないように、サブシェル内にいるかどうかを確認する必要があります。ネストされたシェル レベルは、シェル スタックの '深さ' を格納する bash 環境変数 SHLVL から取得できます。
ログを「クリーン」に保つための注意:
stdin をログ ファイルにリダイレクトすると、スクリプト ユーティリティが生成するのと同じ不要なアーティファクトが多数生成されます。これは、リダイレクトとファイルの間にフィルター ステージ (例: sed/grep) を追加することで対処できます。ログに記録したくないものをすべて削除する正規表現を作成するだけです。完全にクリーンアップするには、かなり詳細な処理が必要になります (ファイルに書き込む前に各新しい行をバッファリングし、それをクリーンアップしてから書き込むなど)。そうしないと、バックスペースが「ゴミ」なのか意図されたのかを判断するのが難しくなります。
答え2
従来の方法は、PuTTY を使用して数千行を保持することでした。多くの Linux (またはローカル) ユーザーが PuTTY を使用しないため、screen もあります。
現在、Windows にはコマンド ラインで ssh が使えるようになっていますが、これは時代遅れになりつつあります。