Сохранить всю команду и весь вывод (используя скрипт через терминалы)
В течение короткого периода времени я хочу сохранить историю команд и вывод каждой команды, которую я запускаю в любом терминале, который я открываю. Все должно идти в одном файле.
Поэтому я хочу выполнить команду (или отредактировать 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
также.