我有一个bash脚本,我需要从中编写日志。目前我使用像下面那样的块
#log stop request
{
local now=$(date +"%a %b %d %Y %H:%M:%S")
printf "batch stop request successful. \n"
printf " Time :: %s\n" "$now"
printf " PID of process :: %s\n" ${PID[0]}"
} >> "${mylogfile}"
其中mylogfile变量将具有日志文件的名称。
这种方法的问题在于,当有两个或更多实例运行时,日志往往会被来自交错实例的写入搞乱。
请注意我使用的块认为它会导致日志一次写入文件,从而避免了这个问题。
我见过来自Vivek Gite post的记录器命令。但问题是它没有写入我可以指定的文件,而是写入/ var / log / message。
非常感谢任何帮助。
谢谢和问候 思碧
答案 0 :(得分:3)
POSIX(IEEE Std 1003.1-2001)没有定义将数据发送到同一文件的并发write()系统调用的行为,因此根据您的平台,您可能会获得不同的结果。您可以尝试将所有printfs
合并为一个,希望这可以工作,但即使它确实存在,也不能保证它将来或不同的平台。
不是使用并发控制和刷新来确保写入顺序,您可以将消息发送到第三个进程,该进程将代表所有进程将日志消息顺序写入文件。事实上,这就是您引用的post中logger
和syslog
所做的事情。 logger
命令不会将消息发送到/var/log/messages
。它将日志消息发送到syslog
,可以将其配置为将日志消息保存在您喜欢的任何位置。但是,更改此配置通常需要管理权限。
如果您不能或不想使用syslog
,您还可以使用netcat作为日志记录服务器。运行此命令将所有脚本中的所有传入日志消息多路复用到文件中(此作业应始终在后台运行,您也可以在screen中运行):
nc -luk localhost 9876 > shared_log_file &
(端口9876只是一个例子)并以这种方式登录每个脚本:
printf "Log message\n" > /dev/udp/localhost/9876
您也可以使用自定义UDP服务器而不是netcat(例如this one)。
答案 1 :(得分:2)
正如您所发现的,该块不会以任何方式对printfs进行分组。但是,您可以做的是在子shell(括号之间)中执行所有这些命令,然后重定向子shell的输出!
答案 2 :(得分:1)
尝试将3个printfs作为一个字符串,即
printf "Epsilon batch stop request successful. \n Time :: %s\n PID of process :: %s\n" "$now" ${PID[0]}
你仍然可以进行交错。
为什么不使用自己的日志文件启动每个实例,使用日志文件名称上的$ {PID}将它们分开?即。
>> "${mylogfile}.${PID}"
修改强>
正如您希望使用记录器一样,请查看手册页:
logger(1) - Linux man page
Name
logger - a shell command interface to the syslog(3) system log module
Synopsis
logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...]
Description
Logger makes entries in the system log. It provides a shell command interface to the syslog(3) system log module.
Options:
-i' Log the process id of the logger process with each line.
-s' Log the message to standard error, as well as the system log.
-f file
Log the specified file.
.....
这看起来像你想要的。
我希望这会有所帮助。
答案 3 :(得分:1)
根据日志记录的性质,它可能非常适合系统日志而不是其私有日志文件。在这种情况下,logger
程序可能是手动记录的一个非常好的替代方案。