Дата и время публикации:
Суть проблемы и решение
1. Проблема
Который заключается в основном не в поиске путей включения трассировки выполнения команд в BASH,а их возможность журналирования в отдельном файле и получения, например, их полного пути и размера, как показано в листинге 1.1 .
Листинге 1.1
#!/bin/bash -x
...
ls /bin/bash
df | egrep 'home\|rootfs'
users
echo "The log file contains some command that were ran in SHELL"
echo "done."
Выполнение которого будет выполняться в перемешку с выводом не только название самих команд (с префиксом "+") на устройства вывода ошибок (STDERR), как показано в дампе 1.2, отображающий печать их выполнения на стандартное устройства STDOUT
Листинге 1.2
+ date +%c-%s + ls /bin/bash /bin/bash + df + egrep 'home\|rootfs' + users user + echo 'The log file contains some command that were ran in SHELL' The log file contains some command that were ran in SHELL + echo done. done.
2. Решение
Для чего, сначала рассмотрим две основных формы одновременного перенаправления со стандартного устройства вывода STDOUT (файловый дескриптор 1) и стандартного вывод ошибок STDERR (файловый дескриптор 2) в файл, который обозначается далее word [3.1].
- Первая форма : &>word
- Вторая и предпочитаемая форма первой: >&word
Вторая форма является семантически эквивалентной и наиболее популярной : >word 2>&1, как показано в листинге 2.1.
Листинге 2.1
#!/bin/bash -x ... exec > $PWD/bash_log.out 2>&1
Перенаправляя весь поток сообщений с STDOUT и STDERR в файл с начала до конца выполнения скрипта . При этом нужно помнить, что все летящие сообщения будут направлены прямо в файл $PWD/bash_log.out минуя всех и вся [3.3]...
Поэтому, если укажем 2> $HOME/bash_log.stderr вместо exec > $HOME/bash_log.out 2>&1, который закоментировали, как показано в листинге 2.2
Листинге 2.2
#!/bin/dash -x ... #exec > $HOME/bash_log.out 2>&1 exec 2> $HOME/bash_log.stderr ...
На выходе которого получим некоторый файл, прочитав который с некоторой фильтрацией, которая показана в листинге 2.3
Листинге 2.3
... cat bash_log.stderr | sed 's/^[+]\{1,2\}[[:space:]]\(.*\)$/\1/' | awk '{ print $1 }' | xargs which | xargs stat --printf="%n\t\t%x\t\t%s\n" ...
Получим на выводе абсолютные пути, полученные which, и размеры, извлеченные по ним stat --printf="%n\t\t%x\t\t%s\n" [3.1], всех используемых команд и зарегистрированных команд в файле $HOME/bash_log.stderr, как показано в дамп 2.4
Листинге 2.4
Пн 29 мар 2021 09:32:11-1616999531 ... /usr/bin/ls 2021-03-29 09:03:33.749229414 +0300 147176 /usr/bin/df 2021-03-29 09:16:58.370080238 +0300 93936 /usr/bin/egrep 2021-03-29 09:16:58.370080238 +0300 28 /usr/bin/users 2021-03-29 09:28:46.773728789 +0300 39744 /usr/bin/echo 2021-03-29 08:56:59.487833562 +0300 39712 /usr/bin/echo 2021-03-29 08:56:59.487833562 +0300 39712
Но, если вывести время, как было показано только что в дампе выше, то увидим, что есть небольшая засада, а именно, что ни одно из значение времени доступа к файлу, выведенное утилитой STAT, не соответствует времени начала регистрации запуска команд, выведенная командой date.
Но, это уже иная история...
3. Библиография
3.1 BASH. Redirecting Standard Output and Standard Error