/dev/vcs[a]<n>
sprawi, że ostatni ekran będzie pełny, nawet jeśli przewinąłeś w górę, ale wybrana opcja ioctl()
s gpm
pozwoli ci zrzucić aktualnie wyświetlany ekran nawet po przewinięciu w górę.
Możesz więc zrobić:
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
Dostosuj 80 i 25 do rzeczywistej szerokości i wysokości ekranu.
sleep 3
Daje czas do przewijania w górę (z Shift+PageUP) do rzeczywistego ekranu chcesz zrzucić. cat > file
przekierowuje wklej do file
. Zakończ to za pomocą Ctrl+D.
Zobacz console_ioctl(4)
szczegóły.
Jeśli masz gpm
zainstalowany i uruchomiony, możesz dokonać wyboru za pomocą myszy.
Przewijanie i wybór wirtualnej konsoli Linuxa jest bardzo ograniczony i dość irytujący (w tym momencie, gdy zmieniasz konsolę, tracisz całe przewijanie). Idąc dalej, sugeruję, abyś używał takich rzeczy jak GNU screen
lub tmux
w nim (osobiście używam ich w jeszcze bardziej wydajnych terminalach). Dzięki nim możesz mieć większe przewijane strony do przeszukiwania i łatwo zrzucić je do plików (a nawet zalogować wszystkie dane wyjściowe terminala oraz wszystkie inne gadżety, które są dostarczane z tymi terminalowymi multiplekserami).
Jeśli chodzi o automatyzację procesu zrzucania całego bufora przewijania, powinno to być możliwe w pewnych warunkach, ale dość trudne, ponieważ interfejs API jest bardzo ograniczony. Istnieje nieudokumentowane ioctl
(TIOCLINUX, subkod = 13) przewijanie bieżącej konsoli wirtualnej o pewne przesunięcie (ujemne przy przewijaniu w górę, dodatnie przy przewijaniu w dół).
Nie ma jednak sposobu (o którym wiem), aby poznać aktualny rozmiar bufora przewijania. Trudno więc wiedzieć, kiedy osiągnąłeś szczyt tego bufora. Jeśli spróbujesz przewinąć obok, ekran nie zostanie przesunięty o tyle i nie ma wiarygodnego sposobu, aby dowiedzieć się, o ile ekran faktycznie przewinął.
Uważam też, że zachowanie przewijanego ioctl jest nieprawidłowe (przynajmniej z konsolą VGA), gdzie przewijanie o mniej niż 4 linie działa tylko sporadycznie.
Poniższy skrypt wydaje mi się działać na konsolach bufora ramki (i czasami na VGA), pod warunkiem, że bufor przewijania nie zawiera sekwencji identycznych linii dłuższych niż jeden ekran plus jedna linia.
Jest dość powolny, ponieważ przewija jedną linię na raz i musi czekać 10 ms na eof podczas czytania każdego zrzutu ekranu.
Do użycia that-script > file
z poziomu wirtualnej konsoli.
#! /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);