Linux仮想コンソールのコンテンツとスクロールバックをファイルに保存することはできますか?


21

長期実行スクリプトがあり、その出力をファイルにリダイレクトするのを忘れていました。ターミナルで表示できますが、ファイルに保存できますか?

を要求していませんtee、出力のリダイレクト(例:>など>>)-コマンドが開始されており、再度実行することはできません。すでに生成された出力を保存する必要があります。ディスプレイに表示される場合は、保存/キャッシュ/バッファリングされています。どこ?

screendump/dev/vcsXなどは、端末出力の最後の画面のみを保存することを可能にします(現在のものではありません!端末をスクロールしても役に立ちません)。

これはgnome-terminal、マウスなどのX11端末エミュレータではなく、Linux仮想コンソール上にあります。


1
はい、あなたはそれを見ることができるので、それはどこかにあります。残念ながら、それはディスプレイ用のハードウェアフレームバッファです。おそらく、ディスプレイハードウェアから取り出すよりも、手で書き写す方が簡単でしょう。
msw

面白い!しかし...のように/dev/、どこかで欠落していますか?そうでなければ、あなたはそれに到達する方法を書きました。
審査員

回答:


19

/dev/vcs[a]<n>上にスクロールしても最後の画面いっぱいになりますが、ioctl()使用する選択sを使用するgpmと、上にスクロールしても現在表示されている画面をダンプできます。

だからできること:

sleep 3; perl -e '
  require "sys/ioctl.ph";
  # copy:
  ioctl(STDIN, &TIOCLINUX, $arg = pack("CS5", 2, 1, 1, 80, 25, 2));
  # paste:
  ioctl(STDIN, &TIOCLINUX, $arg = "\3")'; cat > file

実際の画面の幅と高さに合わせて80と25を調整します。

を使用すると、ダンプする実際の画面sleep 3まで(でShift+PageUP)スクロールアップする時間ができます。cat > file貼り付けをにリダイレクトしfileます。で終了しCtrl+Dます。

詳細console_ioctl(4)を参照してください。

gpmインストールして実行している場合は、マウスでその選択を行うことができます。

Linux仮想コンソールのスクロールバックと選択は非常に限られており、非常に面倒です(コンソールを切り替えると、スクロールバック全体が失われます)。今後、私はあなたがGNUのようなものを使用することをお勧めしたいscreenか、tmuxその中に(私は個人的にも、より多くの可能な端末でそれらを使用します)。それらを使用すると、より大きな検索可能なスクロールバックを使用して、それらをファイルに簡単にダンプできます(さらに、すべてのターミナル出力に加えて、それらのターミナルマルチプレクサに付属するすべてのグッズを記録できます)。


スクロールバックバッファー全体をダンプするプロセスを自動化することに関しては、ある条件下では可能ですが、APIが非常に限られているため非常に困難です。文書化されていないioctl(TIOCLINUX、subcode = 13)があり、現在の仮想コンソールをオフセット(スクロールアップでは負、スクロールダウンでは正)だけスクロールします。

ただし、スクロールバックバッファの現在のサイズを知る方法はありません(私が知っていることです)。そのため、いつそのバッファーの最上部に到達したかを知るのは困難です。それを超えてスクロールしようとすると、画面はそれほどシフトされず、画面が実際にスクロールした量を知る信頼できる方法はありません。

また、スクロールするioctlの振る舞い(少なくともVGAコンソールでは)を見つけます。4行未満のスクロールはたまにしか機能しません。

以下のスクリプトは、スクロールバックバッファーに1画面+ 1行より長い同一行のシーケンスが含まれていない場合、フレームバッファーコンソール(およびVGAのコンソール)で動作するようです。

一度に1行ずつスクロールし、各画面ダンプを読み取るときにeofを10ミリ秒待つ必要があるため、非常に低速です。

that-script > file仮想コンソール内から使用する場合。

#! /usr/bin/perl
require "sys/ioctl.ph";
($rows,$cols) = split " ", `stty size`;
$stty = `stty -g`; chomp $stty;
system(qw(stty raw -echo icrnl min 0 time 1));

sub scroll {
  ioctl(STDIN, &TIOCLINUX, $arg = pack("Cx3l", 13, $_[0])) or die "scroll: $!";
}
sub grab {
  ioctl(STDIN, &TIOCLINUX, $arg = pack("CS5", 2, 1, 1, $cols, $rows, 2)) or die "copy: $!";
  ioctl(STDIN, &TIOCLINUX, $arg = "\3") or die "paste: $!";
  return <STDIN>;
}
for ($s = 0;;$s--) {
  scroll $s if $s;
  @lines = grab;
  if ($s) {
    last if "@lines" eq "@lastlines";
    unshift @output, $lines[0];
  } else {
    @output = @lines;
  }
  @lastlines = @lines;
}
print @output;
exec("stty", $stty);

0

https://github.com/jerome-pouiller/reredirect/はオプションでしょうか?

説明:

reredirectは、既存の実行中のプログラムを取得し、その出力(標準出力およびエラー出力)をファイルまたは別のプロセスに添付するためのユーティリティです。

構文は次のとおりです。

reredirect -m FILE PID

7
これは、OPが要求したように既に生成された出力を保存せず、新しい出力のみがどこかにリダイレクトされます。
-jimmij

1
それは本当です
...-Adionditsak

それで、私のプログラムがすでに終了している場合、ディスプレイの写真しか撮れませんか?
審査員
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.