我的同事写了如下脚本:
echo "nightly $MACHINE restart begins at" `date`
输出如下内容:
nightly whitestar restart begins at Mon Oct 13 22:05:01 EDT 2014
然而,尝试解析它以进行修剪或错误检测是很困难的!此外,似乎
`date`
根据有关子 shell 的在线讨论(以及我对反引号的普遍厌恶),这不是输出日期的最有效方法。
有没有更好的方法来提供相关信息,使其更简洁、更高效、更易于解析?
答案1
在纯 中/bin/sh
,生成date
是主要方式。但这并不是那么糟糕——Linux 和 BSD 创建新进程的速度都相当快,并且二进制date
文件将在内存中缓存一段时间。如果您不喜欢反引号的外观,$(this syntax)
通常比它们更受欢迎。
您可以使用更改日期格式date +fmt
,为其提供 strftime() 样式的格式:
echo "nightly $MACHINE restart at $(date +"%F %T %z")"
echo "$(date +"%F %T %z"): $MACHINE: nightly restart"
...实际上,您可以扩展日期格式选项以date
打印整行 - 只要您避免或转义%
变量中的字符即可:
date +"%F %T %z: $MACHINE: nightly restart"
在 Bash shell 中,您可以echo
用替换printf
,并使用特殊%(fmt)T
格式说明符,它再次接受 strftime() 样式的格式:
printf "%(%F %T %z)T: %s: nightly restart\n" "$MACHINE"
在上述所有例子中,%F %T %z
(或完整版本%Y-%m-%d %H:%M:%S %z
)是“修改后的ISO 8601“日期格式。 (常规 ISO 8601 为%FT%T%z
或%Y-%m-%dT%H:%M:%S%z
,可读性稍差。)在格式化日期以供将来解析时,这两种方式通常都是最佳选择。
最后,你可以echo
完全忘记,直接写入系统日志。大多数操作系统都带有logger
发送到系统日志:
logger -s -p user.notice "nightly restart"
系统日志将自动存储日期和时间以及主机名。
答案2
许多人没有意识到,它date(1)
本身可以代替 echo — 消息是格式的一部分。例如:
date '+%D %T nightly restart'
这比通常使用反引号捕获日期输出更简单、更直接。除非重定向到日志文件,否则日志消息可能应该发送到stderr
而不是stdout
:
date '+%D %T nightly restart' 1>&2
这是我最喜欢的方法。唯一更好的选择是——正如上文中 grawity 指出的那样——使用 bash 的内置实现printf(1)
。当然,它的缺点是,你的脚本变成了仅限 bash 的脚本……
如果您也需要将记录发送到 syslogd,则应该使用logger(1)
(使用-s
)——正如 grawity 所建议的那样——请记住,该标志并非在所有系统上都可用。例如,令人恼火的是,Solaris(包括 Solaris-10)上缺少该标志。(并非巧合的是, “Slowlaris”上也缺少LOG_PERROR
定义(某些实现可以syslog(3)
识别)...)
答案3
lecho 0.3
对于过去的日志记录,我们使用了以下内容:
server=$( uname -n )
lecho() {
now=$( date '+%Y-%m-%d %T' )
printf "[%19s]%s@%s\n: %s\n" "$now" "$USER" "$server" "$@"
}
# ...
lecho "BEGIN nightly restart"
编辑:当你做很多这样的事时,printf 比 echo 更快。此外,输出的格式对以后查找非常有用。