Linuxの「スクリプト」コマンドhttp://www.linuxcommand.org/man_pages/script1.htmlを使用して、 いくつかの対話型セッションを追跡しています。からの出力ファイルには、バックスペースキーストロークを含む印刷できない文字が含まれています。
これらの出力ファイルを整理して、画面に表示されたものだけを含める方法はありますか?
または、対話型のシェルセッション(入力および出力)を記録する別の方法はありますか?
Linuxの「スクリプト」コマンドhttp://www.linuxcommand.org/man_pages/script1.htmlを使用して、 いくつかの対話型セッションを追跡しています。からの出力ファイルには、バックスペースキーストロークを含む印刷できない文字が含まれています。
これらの出力ファイルを整理して、画面に表示されたものだけを含める方法はありますか?
または、対話型のシェルセッション(入力および出力)を記録する別の方法はありますか?
回答:
ファイルを表示したい場合は、を介して出力を送信できますcol -bp
。これは制御文字を解釈します。必要に応じて、パイプスルーを少なくすることができます。
col -bp typescript | less -R
一部のシステムでcol
は、ファイル名引数を受け入れないため、代わりに次の構文を使用します。
col -bp <typescript | less -R
col
は、ファイル名を受け入れないので、col -bp < typescript
やりたいことをやりました。
less -R
、col -bp
最初にパイピングするよりも出力が優れています。
col -bp <typescript | less -R
しても、色付きのコンソールは表示されません。を使用less -R typescript
すると、色付きのコンソールが表示されます!
less
。
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed
以下は、への文字列入力の解釈ですperl
。
s/pattern//g
g
入力文字列全体で置換を行うことを意味します(オプションは、最初の置換で停止するのではなく、すべてを行うことを意味します)入力文字列正規表現パターンの解釈は次のとおりです。
\e
特別な「エスケープ」制御文字(ASCII 0x1A)と一致(
そして )
、グループの始まりと終わりです|
グループがN個のパターンのいずれかに一致できることを意味します。Nパターンは
[^\[\]]
または\[.*?[a-zA-Z]
または \].*?\a
[^\[\]]
手段
[
し、]
\[.*?[a-zA-Z]
手段
[
貪欲ではない.*?
\].*?\a
手段
]
押す.*?
まで貪欲でないことを行います。typescript
するperl
プログラムに出力をエコーし、出力をunix col
コマンドにパイプします。unix コマンド-b
は、転写の「削除」キーアーティファクトを削除します。次に、出力をテキストファイルにパイプします。
大量のscript
出力を得るには、perlスクリプトを繰り返しハッキングします。それ以外の場合は、優れたエディターを使用して手動で編集します。
script
特定の重要な瞬間(ホストがそれを待っているときなど)に画面に表示されたものを再現する方法で、出力から制御文字を削除する既存の自動化された方法はありそうにありませんユーザー入力の最初の文字を。
たとえば、を除く画面が空白になるAndrew $
場合がありますrm /*
。12回(必要以上に)入力してバックスペースを押した場合、画面の最後に表示される内容は、実行中のシェル、現在のstty
設定(これはセッションの途中で変更される可能性があります)、おそらく他のいくつかの要因も含まれます。
上記は、入力および出力を継続的にキャプチャする自動化された方法に適用されます。主な代替手段は、セッション中の適切な時間に「スクリーンショット」を撮るか、スクリーンを切り取って貼り付けることです(これは、ユーザーガイドや日誌のメモなどで行います)。
私の質問の2番目の部分に対する答えは、gnu画面でロギング機能を使用することです:^A H
実行中の画面セッション内から。ドキュメントはhttp://www.gnu.org/software/screen/manual/screen.html#Loggingにあります
cat filename
制御文字を削除するために使用しました:-)
col -bpは、必要に応じてバックスペースを処理します(AFAIK)。ただし、カラーエスケープシーケンスは破損します。可能であれば、最初にカラーシーケンスを削除してから、バックスペースを処理することをお勧めします。
これは非常に一般的なニーズであり、それに対する解決策がこれ以上ないことに驚いています。セッションをスクリプト化することは非常に一般的であり、誰かが手順を確認する必要があります。小さな入力ミスをすべて取り除き、エスケープシーケンスを色分けして、将来の参照のために手順の「クリーンな」スクリプトを作成します。シンプルなASCIIテキストを推奨。これは「人間が読める」ことによって意図されたものであり、非常に合理的なことだと思います。
dewtallが提供する答えを見つけましたPerlが利用できる環境にいる場合がUnixボード上の同様の質問に、スクリプトの出力から制御文字を削除するのにより効果的であることが。
dewtallのスクリプト:
#!/usr/bin/perl
while (<>) {
s/ \e[ #%()*+\-.\/]. |
\r | # Remove extra carriage returns also
(?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
(?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
(?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
\e.|[\x80-\x9f] //xg;
1 while s/[^\b][\b]//g; # remove all non-backspace followed by backspace
print;
}
制御文字を削除するには:
./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed
https://github.com/RadixSeven/typescript2txtは、この問題を解決するために作成されました。
最後に更新/使用してから4年が経過しましたが、今日はまだ動作しないはずの空想をしたことを覚えていません。
良い方法を見つけました。私のシステムでは、長い出力行に "^ M"(空白スペースの後にキャリッジリターンが続く)が散在しています。「^ M」は、ファイルをcatしたときにまったく表示されないヌル文字「^ @」にうまく置き換えることができます。
タイミングもキャプチャするため、ファイルを完全に再生するために、以下のコマンドを使用して「^ M」を完全に削除することはできません(scriptreplayはバイトをカウントするため)。
tr '\r' '\0' | sed 's/ \x0//g'
次のようにスクリプトコマンドを実行します。
script -t -f session.log 2>timing
だから、その後私がやることは:
cat session.log | tr '\r' '\0' > typescript
scriptreplay -t timing | sed 's/ \x0//g'
最初の編集(リプレイ前)は、ファイル内のバイト数を保持します。2番目の編集(再生後)は、ランダムな場所の空白を取り除きます。(デフォルトでは、scriptreplayは「typescript」という名前の入力ファイルを探すため、「timing」の後に指定しなかったことに注意してください。)
もう1つの解決策はstrings
、ファイル(または標準入力)から印刷可能な文字のみを印刷するものを使用することです。
strings -n 1 filename
この-n 1
オプションは、保存されるシーケンスの最小長を1に設定するため、印刷できない文字に囲まれた単一の印刷可能な文字も保存されます。
このアプローチの1つの考えられる欠点はstrings
、印刷可能な文字の連続した文字列の間に改行が追加されることです。たとえば、コンテンツを含むファイル
Foo<SOMECONTROLCHAR>Bar
(<SOMECONTROLCHAR>
制御文字またはその他の印刷できない文字)は次のように返されます
Foo
Bar
コメントで提起された別の問題は、制御文字のシーケンスの一部が印刷可能文字と印刷不可文字の両方の組み合わせで構成され、このアプローチではそれらの一部のみが削除されることです。
ただし、strings
質問で言及されているバックスペースのような制御文字を削除するのは良い仕事です。
strings
すべての印刷不能文字を削除しません。印刷可能な文字のシーケンスを識別して印刷します。それは同じことではありません。
strings
では最小長4のシーケンスのみを出力-n 1
します。最小長を1に設定するオプションを追加することにより、答えを修正しました。これを指摘してくれてありがとう。
strings
すべての非印刷可能文字を削除するという同じ主張を依然として行っているため、編集前と同じように間違っています。また、「一部のカラーコード」(および一般に制御コード)が印刷可能な文字と印刷できない文字の両方で構成されることが多いため、明らかに壊れています。たとえば、テキストの色を変更するための制御コードシーケンスがあるかもしれないESC[01;52m
どこESC
シングルエスケープ文字(バイト値27)があります。strings
提案どおりに使用する[01;52m
と、出力に残りますが、これは無意味です。
strings
他の回答のいくつかと同じ仕事をしないかもしれませんが、私見は質問で説明されている問題を解決するための有効なアプローチです。