Сохранить всю команду и весь вывод (используя скрипт через терминалы)

В течение короткого периода времени я хочу сохранить историю команд и вывод каждой команды, которую я запускаю в любом терминале, который я открываю. Все должно идти в одном файле.

Поэтому я хочу выполнить команду (или отредактировать bashrc) так, чтобы я мог тогда;

  • Откройте терминал № 1 и запустите echo hello
  • Откройте терминал № 2 и введите ls
  • Закройте терминал № 1, откройте терминал № 3 и введите whoami
  • Закройте все терминалы. Откройте терминал № 4 и введите команду, чтобы увидеть, как все команды выполняются в указанном выше порядке (echo hello, ls, whoami), плюс их вывод, в порядке я запускал команды.

Я мог бы теоретически открыть каждый терминал и набрать

screen -f output.txt

а потом

exit

прежде чем я закрыл каждый терминал, но я не хочу помнить, чтобы набирать это каждый раз. Я просто хочу, чтобы это делалось автоматически, пока я не остановлю его вручную (запустив команду или обновив bashrc).

Пожалуйста, внимательно прочитайте вопрос, прежде чем объявить его дубликатом. Я искал существующие вопросы и не нашел что-то эквивалентное (хотя возможно я пропустил это).

1 ответ

Потенциальное решение

После некоторых исследований и экспериментов, вот что я придумал:

logstuff(){

    while true; do

        case $1 in
            "on" ) exec > >( ( printf ">>>>> TIME:$(date) SHELLPID:$$;\n"; tee /dev/tty ; printf ">>>>>\n" ) >> logfile.txt) 2>&1 ;
                   break;;
            "off") exec > /dev/tty 2>&1 ;
                   break;;
                *) echo "Please type 'on' or 'off';;
        esac
    done
}

Эта функция Bash должна быть размещена в вашем ~/.bashrc и доступен для использования при открытии нового терминала или после выдачи source ~/.bashrc, Регистрация должна быть включена вручную через on а также off аргументы.


DEMO

Вот как это работает на практике:

Делать вещи в оболочке 1:

<shell 1>$ logstuff on
<shell 1>$ stat /etc/passwd
  File: /etc/passwd
  Size: 2208            Blocks: 8          IO Block: 4096   regular file
Device: 802h/2050d      Inode: 156236      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-12-01 20:24:02.620000000 +0000
Modify: 2018-10-31 01:33:42.701000999 +0000
Change: 2018-10-31 01:33:42.704998999 +0000
 Birth: -
<shell 1>$ logstuff off
<shell 1>$ 

Делать вещи в оболочке 2:

< shell 2 >$ logstuff on
< shell 2 >$ echo "Hello World !"
Hello World !
< shell 2 >$ logstuff off
< shell 2 >$ 

Теперь рассмотрим logfile.txt:

<shell 1>$ cat logfile.txt 
>>>>> TIME:Sat Dec  1 21:43:00 UTC 2018 SHELLPID:2225;
<shell 1>$ stat /etc/passwd
  File: /etc/passwd
  Size: 2208            Blocks: 8          IO Block: 4096   regular file
Device: 802h/2050d      Inode: 156236      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-12-01 20:24:02.620000000 +0000
Modify: 2018-10-31 01:33:42.701000999 +0000
Change: 2018-10-31 01:33:42.704998999 +0000
 Birth: -
<shell 1>$ >>>>> TIME:Sat Dec  1 21:43:11 UTC 2018 SHELLPID:2359;
< shell 2 >$ echo "Hello World !"
Hello World !
< shell 2 >$ logstuff off
>>>>>
logstuff off
>>>>>
<shell 1>$ 

вопросы

  • Если logstuff on сначала выдается в обоих терминалах, есть вероятность, что выходы будут искажены вместе. Это работает так, что вы должны выдать logsutff on в оболочке 1, затем выполните команды там, затем выполните logstuff on в оболочке 2.
  • Это использует процесс замены >( ), tee и подоболочка. Не самый элегантный и не эффективный из-за большого количества разветвлений и дополнительного трубопровода.
  • logfile.txt хранится в текущем рабочем каталоге. Это должно быть изменено на ~/logfile.txt или, однако, пользователь считает нужным.

Практические соображения

То, что сам вопрос задает, несколько непрактично: хранение выходных данных из нескольких оболочек в одном файле означает, что вы сохраняете выходные команды из двух или более совершенно не связанных сессий, которые могут иметь разные переменные среды, разные рабочие каталоги или работать на разных файловых системах.; это означает, что отсутствует много контекста, если вы собираетесь использовать такой текст журнала для отладки или решения проблемы.

Гораздо лучший подход будет иметь script -f запись в файлы журналов в одном конкретном каталоге, возможно, с именами файлов таких журналов с метками времени или с добавленным PID оболочки. Другое решение - вместо 3 разных терминалов, просто используйте один - screen или мой личный фаворит byobu-screen, Вы можете присоединить / отсоединить к одному виртуальному tty-сеансу на экране, и он часто используется для поддержки процессов, запущенных на удаленных серверах, на которых вы должны выйти из системы, но при этом все еще нужен сеанс оболочки с запущенными выходными данными и трассировками. Это можно сочетать с script также.

Другие вопросы по тегам