Có thể lưu nội dung bảng điều khiển ảo Linux và cuộn lại trong một tệp không?


21

Tôi có một tập lệnh chạy dài hạn và tôi quên chuyển hướng đầu ra của nó thành một tập tin. Tôi có thể nhìn thấy nó trong một thiết bị đầu cuối, nhưng tôi có thể lưu nó vào một tập tin không?

Tôi không yêu cầu tee, chuyển hướng đầu ra (ví dụ >, >>v.v.) - lệnh đã bắt đầu và tôi không thể chạy lại. Tôi cần lưu đầu ra đã được tạo. Nếu tôi có thể nhìn thấy nó trên màn hình của mình, nó ở đâu đó được lưu trữ / lưu trữ / đệm. Ở đâu?

screendump, /dev/vcsXv.v. cho phép tôi chỉ lưu màn hình cuối cùng trên đầu ra của thiết bị đầu cuối (không phải hiện tại! - thiết bị đầu cuối cuộn không giúp ích).

Đây là trên bảng điều khiển ảo Linux, không phải trình giả lập thiết bị đầu cuối X11 như gnome-terminalvới chuột và các tính năng khác.


1
Vâng, vì bạn có thể nhìn thấy nó, nó ở đâu đó. Thật không may, đâu đó là bộ đệm khung phần cứng cho màn hình. Có lẽ sẽ dễ dàng hơn để sao chép nó bằng tay hơn là tách nó ra khỏi phần cứng màn hình.
msw

Hấp dẫn! Nhưng ... nó bị thiếu ở đâu đó, như trong /dev/, phải không? Mặt khác, bạn đã viết làm thế nào để đạt được nó.
Ban giám khảo

Câu trả lời:


19

/dev/vcs[a]<n>sẽ chỉ giúp bạn có màn hình đầy đủ cuối cùng ngay cả khi bạn đã cuộn lên, nhưng các lựa chọn ioctl()như được sử dụng gpmsẽ cho phép bạn bỏ màn hình hiện đang hiển thị ngay cả khi bạn cuộn lên.

Vì vậy, bạn có thể làm:

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

Điều chỉnh 80 và 25 theo chiều rộng và chiều cao màn hình thực tế của bạn.

Việc này sleep 3cho bạn thời gian để cuộn lên (với Shift+PageUP) đến màn hình thực tế mà bạn muốn kết xuất. cat > filechuyển hướng dán để file. Hoàn thành nó với Ctrl+D.

Xem console_ioctl(4)để biết chi tiết.

Nếu bạn đã gpmcài đặt và chạy, bạn có thể thực hiện lựa chọn đó bằng chuột.

Việc lựa chọn và cuộn lại bảng điều khiển ảo Linux rất hạn chế và khá khó chịu (trong đó khi bạn chuyển giao bảng điều khiển, bạn sẽ mất toàn bộ cuộn ngược lại). Đi tiếp, tôi khuyên bạn nên sử dụng những thứ như GNU screenhoặc tmuxbên trong nó (cá nhân tôi sử dụng chúng trong các thiết bị đầu cuối có khả năng hơn nữa). Với chúng, bạn có thể có các cuộn ngược có thể tìm kiếm lớn hơn và dễ dàng chuyển chúng vào các tệp (và thậm chí ghi nhật ký tất cả đầu ra của thiết bị đầu cuối, cộng với tất cả các tính năng khác đi kèm với các bộ ghép kênh đầu cuối đó).


Để tự động hóa quá trình kết xuất toàn bộ bộ đệm cuộn, điều này có thể xảy ra trong một số điều kiện, nhưng khá khó khăn vì API rất hạn chế. Có một tài liệu không có giấy tờ ioctl(TIOCLINEUX, mã con = 13) để cuộn bảng điều khiển ảo hiện tại bằng một số bù (âm cho cuộn lên, dương để cuộn xuống).

Tuy nhiên, không có cách nào (mà tôi biết) để biết kích thước hiện tại của bộ đệm cuộn. Vì vậy, thật khó để biết khi nào bạn đạt đến đỉnh của bộ đệm đó. Nếu bạn cố cuộn qua màn hình, màn hình sẽ không bị dịch chuyển nhiều và không có cách nào đáng tin cậy để biết màn hình đã thực sự cuộn bao nhiêu.

Tôi cũng thấy hành vi của ioctl cuộn không ổn định (ít nhất là với bảng điều khiển VGA), trong đó việc cuộn dưới 4 dòng chỉ thỉnh thoảng hoạt động.

Kịch bản bên dưới dường như hoạt động với tôi trên các bảng điều khiển bộ đệm khung (và đôi khi trên các bộ VGA) với điều kiện bộ đệm cuộn không chứa các chuỗi giống hệt nhau dài hơn một màn hình cộng với một dòng.

Nó khá chậm vì nó cuộn một dòng mỗi lần và cần đợi 10ms cho eof khi đọc từng kết xuất màn hình.

Được sử dụng như that-script > filetừ trong bảng điều khiển ảo.

#! /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/ có thể là một lựa chọn?

Sự miêu tả:

reredirect là một tiện ích để lấy một chương trình đang chạy và gắn các đầu ra của nó (đầu ra tiêu chuẩn và đầu ra lỗi) vào các tệp hoặc một quy trình khác.

Cú pháp như sau:

reredirect -m FILE PID

7
Điều này không lưu đầu ra đã được tạo như OP yêu cầu, chỉ đầu ra mới sẽ được chuyển hướng ở đâu đó.
jimmij

1
Đó là sự thật ...
Adionditsak

Vì vậy, nếu chương trình của tôi đã kết thúc, tôi chỉ có thể chụp ảnh màn hình của mình?
Ban giám khảo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.