当脚本运行时,当脚本的输出写入同一个日志文件时,我可以读取脚本中的日志文件吗?

当脚本运行时,当脚本的输出写入同一个日志文件时,我可以读取脚本中的日志文件吗?

我有一个 shell 脚本,它将输出写入 some_log_file.log 文件。

{

some logic..

if grep -iq "No such file or directory" some_log_file.log ; then

some logic to send email.. attaching the same some_log_file.log

fi

} >> some_log_file.log 2>&1

如果您观察上面的代码,就会发现脚本在运行时正在检查它正在写入的同一日志文件。这是有效的。但是,这是允许的、标准的吗?

答案1

是的,这是允许的。不,我认为这不是很常见或标准。不过,既然它正在工作,你就可以保持原样。

但就 Panki 的观点而言:仅检查可能报告“没有此类文件或目录”的命令的退出状态(又称返回状态)而不是 grep 日志会更好、更高效。

变量$?始终包含最后执行的命令的退出状态。通常为 0 表示命令运行成功。如果它是正值(1、2、99,等等),则表明存在某种类型的故障。例如:

>> ls /usr/bin/sed
-rwxr-xr-x  1 root  wheel  202960 May  9 15:30 /usr/bin/sed
>> echo $?
0

>> ls -l nonexistent_file
ls: nonexistent_file: No such file or directory
>> echo $?
1

您的命令可能会报告“没有这样的文件或目录”,ftp 是什么?为了简单起见,我们假设它是“ls”。您的脚本可能如下所示:

ls $my_file  # Or whatever your command is.
if [ $? = 1 ]; then
    # Send mail ...
fi

# Alternatives:

ls $my_file  # Or whatever your command is.
if [ $? != 0 ]; then
    # Send mail ...
fi

ls $my_file  # Or whatever your command is.
status=$?
case $status in
    0) : ;;  # Success, do nothing.
    1) Send mail ... ;;
    *) echo "Error: \"ls $my_file\"." returned status $status."
       exit 99;;
esac

如果您的命令是 ftp,则该命令具有更复杂的状态代码,解释如下:

https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes

和这里:

https://docs.microsoft.com/en-us/troubleshoot/developer/webapps/iis/ftp-service-svchost-inetinfo/ftp-status-codes-iis-7-and-later-versions

您还可以使用带有 -f(跟随)选项的 tail 命令进行调查。例如,您可以在后台运行如下命令:

tail -f some_log_file.log | grep -iq "No such file or directory"

有关详细信息,请参阅 tail man(手册)页面。

但我认为使用退出状态($?)将是您的最佳选择。

答案2

对它附加到的文件执行阻塞读取的脚本通常会以挂起的进程结束。

通常的读写工作流程是这样的:脚本等待下一行出现,对其进行处理,并写入一些输出,然后返回等待下一行。

当输出转到脚本正在读取的同一文件时,最终脚本的读取会赶上它正在写入的文件中的同一点。此时,脚本会等待下​​一行,但在脚本写入一些行之前,不会出现行,并且在脚本读取一些新行之前,不会出现这种情况。剧本挂了。

如果其他进程也在写入该文件,则不会发生这种情况。但这通常是一种需要避免的情况。

相关内容