Простой способ сделать это, если он соответствует вашим потребностям, - это иметь специальный файл журнала, который обновляется каждый день. Сначала вы добавляете в / etc / (r) syslog.conf
, вероятно, в самом верху на случай, если есть какие-то правила, которые что-то отбрасывают после регистрации:
*.* -/var/log/daily.log
Он получит все сообщения; то есть все, что есть в любом другом журнале, будет в этом.
Тогда вам просто понадобится скрипт, который можно запустить через cron. Вы можете использовать для этого logrotate
, но в этом случае особого смысла нет.
#!/bin/sh
gzip /var/log/daily.log
# Do whatever with the gzipped file
touch /var/log/daily.log
kill -s HUP `pidof syslogd` # see below
Этот последний шаг необходим для перезапуска syslogd, поэтому он повторно открывает новый /var/log/daily.log
- иначе вы ничего не увидите там после этого. Если вы используете rsyslog, используйте вместо него pidof rsyslogd
. Протестируйте, попробовав pidof
, который когда-либо был первым.
Наконец, в / etc / crontab
:
0 0 * * * root /path/to/rotationscript
Будет делать это в полночь каждый день.
Проще говоря :Поведение оболочки, как ее видят пользователи, не должно измениться, если реализация решит сделать стандартную внешнюю команду также доступной как встроенную -оболочку.
Контраст, который я показал в https://unix.stackexchange.com/a/496291/5132, между поведением (, с одной стороны, )оболочек PD Korn, MirBSD Korn и Heirloom Bourne; (с другой стороны )оболочки Z, 93 Korn, Bourne Again и Debian Almquist; и (на хватающей руке )панцирь Ватанабэ подчеркивает это.
Для оболочек, не имеющих printf
в качестве встроенного -, удаление /usr/bin
из PATH
приводит к прекращению работы вызова printf
.Поведение, соответствующее POSIX, демонстрируемое оболочкой Watanabe в соответствующем режиме, приводит к тому же результату. Поведение оболочки, в которую встроен printf
-, такое , как если бы она вызывала внешнюю команду.
Принимая во внимание, что поведение всех несовместимых -оболочек не меняется, если /usr/bin
удалить из PATH
, и они не ведут себя так, как если бы они вызывали внешнюю команду.
Что стандарт пытается гарантировать вам, так это то, что оболочки могут создавать -во всех видах обычно внешних команд (или реализовывать их как свои собственные функции оболочки ), и вы все равно получите то же самое. поведение встроенных -модулей, как вы делали с внешними командами, если вы настроите PATH
, чтобы запретить поиск команд. PATH
остается вашим инструментом для выбора и управления тем, какие команды вы можете вызывать.
(Как объясняется в https://unix.stackexchange.com/a/448799/5132, много лет назад люди выбирали индивидуальность своего Unix, изменяя то, что было на PATH
.)
Можно подумать, что заставить команду работать всегда независимо от того, можно ли ее найти на PATH
, на самом деле является смыслом создания обычно внешних команд, встроенных -в (. ] Вот почему мой набор инструментов nosh только что получил встроенную команду -в printenv
в версии 1.38. Хотя это не оболочка.)
Но стандарт дает вам гарантию, что вы увидите такое же поведение для обычных внешних команд, которые не включены PATH
из оболочки, как вы увидите из другой оболочки, отличной от -программы, вызывающие функцию execvpe()
, и оболочка волшебным образом не сможет выполнять (видимо )обычные внешние команды, которые другие программы не могут найти с тем же PATH
. Все работает само -последовательно с точки зрения пользователя, и PATH
является инструментом для управления тем, как это работает.
Это довольно абсурдно, поэтому ни одна оболочка не реализует его в режиме по умолчанию.
Обоснование стандарта и его иллюстрирующий пример предполагают, что это была неудачная попытка построить обычный построенный -путь, и пусть пользователь переопределит его, поставив перед ним свой собственный двоичный файл в PATH
(, например. printf
, встроенный -, связанный с /usr/bin/printf
, может быть переопределен внешней командой /foo/bin/printf
, установивPATH=/foo/bin:$PATH
).
Тем не менее, стандарт в конечном итоге требовал не этого, а чего-то совершенно другого (, а также бесполезного и неожиданного ).
Подробнее об этом можно прочитать в этом отчете об ошибке . Цитата из окончательно принятого текста :
Many existing implementations execute a regular built-in without performing a PATH search. This behavior does not match the normative text, and it does not allow script authors to override regular built-in utilities via a specially crafted PATH. In addition, the rationale explains that the intention is to allow authors to override built-ins by modifying PATH, but this is not what the normative text says.
FWIW, я также не думаю, что существует какая-либо оболочка, реализующая пересмотренные требования из принятого текста.
Следуйте -вверх по сравнению с -и -по отношению к echo
по сравнению сprintf
:
(Нижеbuiltin
означает «специальные встроенные функции», а «обычные встроенные функции» я не считаю встроенными, поскольку они не встроены в оболочку)
Первый комитет по стандартизации POSIX не мог договориться о том, как стандартизировать эхо, поэтому они скомпрометировали, выдав, что если оно было передано флаги(-e,-n,-E
и т. д. )или если какие-либо аргументы содержали escape-последовательности(\n,\c,\t
и т. д. ), что поведение должно было определяться реализующей оболочкой а не POSIX. Вместо этого была добавлена команда printf
с четко определенным -поведением. (источник :Классические сценарии оболочки, Роббинс и Биб ).
Хотя printf
хорошо -определено, некоторые оболочки не имеют printf
в качестве встроенная команда (например.mksh
). Вместо этого они используют printf
из /usr/bin/
. Это означало, что все сценарии, запущенные из этой оболочки, будут печатать одно и то же на данная операционная система (Ubuntu, Fedora и т. д. ), но они не обязательно печатать одно и то же в разных ОС (на самом деле, многие пользователи изменили printf
в их /usr/bin
по этой причине ).
Альтернативно, оболочки со встроенным printf
будут печатать то же самое. независимо от ОС, но только если используется так, как реализовано для оболочки. Однако, поскольку поведение printf
определяется стандартом POSIX, это не обязательно забота программистов. Однако, если бы PATH
было переопределено для оболочек, использующих printf
из /usr/bin/
, printf
не было бы найдено.
Хотя все оболочки имеют встроенную функцию echo
, некоторые интерпретируют управляющие последовательности. напрямую (.ash
)в то время как другие (большинство )требуют флага -e
:поведение определяется не POSIX, а оболочкой.
Одно из главных неудобств echo
по сравнению с printf
заключается в том, что echo
печатает новые строки в конце строки по умолчанию, а printf
— нет. printf
требует escape-последовательности \n
для печати новых строк. И наоборот, для предотвращения echo
для печати новой строки требуется управляющая последовательность \c
(потенциально, также требуется флаг -e
).
printf
рекомендуется для максимальной переносимости, так как его поведение определяется POSIX, но я лично считаю, что явная печать новой строки в конце каждой строки довольно раздражает (большинство строк, которые я пишу, требуют новой строки в конце, и я очень редко нужно подавлять echo
печать новых строк ). С другой стороны, echo
всегда доступен, поскольку он является встроенным (нет риска быть не найденным в $PATH )и можно выполнить простую проверку, чтобы определить, нужен ли флаг -e
и соответствующий псевдоним echo
:
#! /bin/sh -
# Determine if "builtin" command exists.
BUILTIN='builtin'
if ! ("${BUILTIN}" echo 123 >/dev/null 2>&1); then
BUILTIN=''
fi
export BUILTIN
ECHO='echo -e'
if ${BUILTIN} [ "`echo -e test`" = '-e test' ]; then
ECHO='echo'
fi
export ECHO
# Now use "${ECHO}" where you would normally use "echo"...
Лично я предпочитаю делать это и использовать printf
, только если мне нужно специальное форматирование.
ОБНОВЛЕНИЕ:Я должен отдать должное там, где это необходимо. Приведенный выше шелл-код был взят непосредственно из shunit2
. Это заслуга Кейт Уорд и команды разработчиков shunit2
! (Молодец ;))