Чи можливо зберегти вміст віртуальної консолі Linux та прокрутку у файл?


21

У мене довготривалий сценарій, і я забув перенаправити його вихід у файл. Я бачу його в терміналі, але чи можу я зберегти його у файлі?

Я не прошу tee, перенаправлення виводу (наприклад >, >>) і т.д. - команда запущена, і я не можу запустити її знову. Мені потрібно зберегти вже створений вихід. Якщо я можу побачити його на своєму дисплеї, він десь зберігається / зберігається в кеші / буфері. Де?

screendump, /dev/vcsXІ так далі дозволяє мені зберегти тільки останній екран на виході терміналу ( а не поточні - термінал прокрутки не допоможе).

Це на віртуальній консолі Linux, а не на емуляторі терміналу X11, як gnome-terminalу миші та інших смаколиків.


1
Так, оскільки ви це бачите, воно десь. На жаль, десь є буфер апаратного кадру для відображення. Можливо, було б простіше переписати його вручну, ніж вирвати з апаратного забезпечення дисплея.
msw

Цікаво! Але ... Він десь відсутній, як у /dev/, правда? Інакше ви написали, як досягти цього.
Журі

Відповіді:


19

/dev/vcs[a]<n>ви отримаєте останній екран повністю, навіть якщо ви прокрутили вгору, але вибір ioctl(), як використовується, 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, підкод = 13) для прокрутки поточної віртуальної консолі деяким зміщенням (негативне для прокрутки вгору, позитивне для прокрутки вниз).

Однак немає (що я знаю) знати поточний розмір буфера прокрутки. Тому важко дізнатися, коли ви досягли вершини цього буфера. Якщо ви спробуєте прокрутити повз нього, екран не буде зміщений на стільки, і немає надійного способу дізнатися, наскільки насправді прокрутив екран.

Я також знаходжу поведінку прокручуваного іоктова прокрутки (принаймні, з консоллю VGA), де прокрутка менш ніж на 4 рядки працює лише зрідка.

Сценарій нижче, здається, працює для мене на консолях буфера кадру (а іноді і на VGA), якщо буфер прокрутки не містить послідовностей однакових ліній, довших за один екран плюс один рядок.

Це досить повільно, тому що він прокручує по черзі один раз, і йому потрібно дочекатися 10 мс для eof під час читання кожного екрана.

Використовується як 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
Це не економить уже створений вихід, як запитував ОП, лише новий вихід буде кудись переспрямований.
jimmij

1
Це правда ...
Адіондітсак

Отже, якщо моя програма вже закінчена, я можу лише сфотографувати свій дисплей?
Журі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.