使用 inotify 和命令行工具监视和搜索文件
monitoring and searching a file with inotify, and command line tools
日志文件由服务器上的水下无人机逐行写入。 T当在地面上时,无人机与服务器的通话速度很慢(比如在不稳定的 phone 线路上约 200o/s)并且只是时不时地(比如每 ~6 小时)。根据消息,我必须在无人机在线时以及挂断其他命令时在服务器上执行命令。其他进程可能正在查看具有类似任务的相同文件。
在这个网站上可以找到很多类似的问题,但我建立的解决方案仍然不能令人满意。目前我正在使用 bash
while logfile_drone=`inotifywait -e create --format '%f' log_directory`; do
logfile=log_directory/${logfile_drone}
while action=`inotifywait -q -t 120 -e modify -e close --format '%e' ${logfile} ` ; do
exidCode=$?
lastLine=$( tail -n2 ${logFile} | head -n1 ) # because with tail -n1 I can got only part of the line. this happens quite often
match =$( # match set to true if lastLine matches some pattern )
if [[ $action == 'MODIFY' ]] && $match ; then # do something ; fi
if [[ $( echo $action | cut -c1-5 ) == 'CLOSE' ]] ; then
# do something
break
fi
if [[ $exitCode -eq 2 ]] ; then break ; fi
done
# do something after the drone has hang up
done # wait for a new call from the same or another drone
主要问题是:
第二个 inotify 漏掉了行,可能是因为其他进程正在查看同一个文件。
我的打卡方式好像不行
无法同时监控2架无人机
基本上代码或多或少可以工作,但不是很健壮。我想知道是否可以通过将第二个 while 循环放在调用时置于后台的函数中来管理问题 3。最后,我想知道更高级别的语言(我熟悉 php,它具有用于 inotify 的 PECL 扩展)是否会做得更好。但是,我认为 php 不会比 bash 更好地解决问题 3。
这是我遇到 while 循环突然退出问题的代码,根据 Philippe's
答案实现,否则工作正常:
while read -r action ; do
...
resume=$( grep -e 'RESUMING MISSION' <<< $lastLine )
if [ -n "$resume" ] ; then
ssh user@another_server "/usr/bin/php /path_to_matlab_command/matlabCmd.php --drone=${vehicle}" &
fi
if [ $( echo $action | cut -c1-5 ) == 'CLOSE' ] ; then ... ; sigKill=true ; fi
...
if $sigKill ; then break; fi
done < <(inotifywait -q -m -e modify -e close_write --format '%e' ${logFile})
当我用 ssh 注释该行时,脚本可以通过 CLOSE 触发的中断正确退出,否则 while loop
在 ssh 命令后突然结束。由于matlab代码运行时间长,ssh放在后台。
monitor mode (-m)
of inotifywait
在这里可能会更好:
inotifywait -m -q -e create -e modify -e close log_directory |\
while read -r dir action file; do
...
done
monitor mode (-m)
不缓冲,它只是将所有事件打印到标准输出。
要保留变量:
while read -r dir action file; do
echo $dir $action $file
done < <(inotifywait -m -q -e create -e modify -e close log_directory)
echo "End of script"
日志文件由服务器上的水下无人机逐行写入。 T当在地面上时,无人机与服务器的通话速度很慢(比如在不稳定的 phone 线路上约 200o/s)并且只是时不时地(比如每 ~6 小时)。根据消息,我必须在无人机在线时以及挂断其他命令时在服务器上执行命令。其他进程可能正在查看具有类似任务的相同文件。
在这个网站上可以找到很多类似的问题,但我建立的解决方案仍然不能令人满意。目前我正在使用 bash
while logfile_drone=`inotifywait -e create --format '%f' log_directory`; do
logfile=log_directory/${logfile_drone}
while action=`inotifywait -q -t 120 -e modify -e close --format '%e' ${logfile} ` ; do
exidCode=$?
lastLine=$( tail -n2 ${logFile} | head -n1 ) # because with tail -n1 I can got only part of the line. this happens quite often
match =$( # match set to true if lastLine matches some pattern )
if [[ $action == 'MODIFY' ]] && $match ; then # do something ; fi
if [[ $( echo $action | cut -c1-5 ) == 'CLOSE' ]] ; then
# do something
break
fi
if [[ $exitCode -eq 2 ]] ; then break ; fi
done
# do something after the drone has hang up
done # wait for a new call from the same or another drone
主要问题是:
第二个 inotify 漏掉了行,可能是因为其他进程正在查看同一个文件。
我的打卡方式好像不行
无法同时监控2架无人机
基本上代码或多或少可以工作,但不是很健壮。我想知道是否可以通过将第二个 while 循环放在调用时置于后台的函数中来管理问题 3。最后,我想知道更高级别的语言(我熟悉 php,它具有用于 inotify 的 PECL 扩展)是否会做得更好。但是,我认为 php 不会比 bash 更好地解决问题 3。
这是我遇到 while 循环突然退出问题的代码,根据 Philippe's
答案实现,否则工作正常:
while read -r action ; do
...
resume=$( grep -e 'RESUMING MISSION' <<< $lastLine )
if [ -n "$resume" ] ; then
ssh user@another_server "/usr/bin/php /path_to_matlab_command/matlabCmd.php --drone=${vehicle}" &
fi
if [ $( echo $action | cut -c1-5 ) == 'CLOSE' ] ; then ... ; sigKill=true ; fi
...
if $sigKill ; then break; fi
done < <(inotifywait -q -m -e modify -e close_write --format '%e' ${logFile})
当我用 ssh 注释该行时,脚本可以通过 CLOSE 触发的中断正确退出,否则 while loop
在 ssh 命令后突然结束。由于matlab代码运行时间长,ssh放在后台。
monitor mode (-m)
of inotifywait
在这里可能会更好:
inotifywait -m -q -e create -e modify -e close log_directory |\
while read -r dir action file; do
...
done
monitor mode (-m)
不缓冲,它只是将所有事件打印到标准输出。
要保留变量:
while read -r dir action file; do
echo $dir $action $file
done < <(inotifywait -m -q -e create -e modify -e close log_directory)
echo "End of script"