我编写了一个脚本来调用inotifywait
。它运行正常,但有时我想停止它。
我该如何停止最后一个inotifywait
实例?
我不明白如何使用inotify_rm_watch
我所理解的方法来关闭它。
7341 ? S 0:00 inotifywait -m /home/andy/Downloads/ --format %w
答案1
您inotify_rm_watch
所指的是在编写“真实”程序(使用 C 或类似语言)时使用的 API(C 函数),而不是脚本。因此它不适用于您的情况。
如果您想停止,inotifywait
可以像其他任何程序一样进行操作:
无论发出什么
ps -ef | grep inotifywait
,挑选 PID(在您的例子中大概是7341
),然后向它发送信号:kill 7341
或者使用便利脚本
killall
杀死全部具有给定名称的程序。killall
通常是默认安装的。killall inotifywait
答案2
使用时存在什么问题kill <pid>
?
您可能有多个inotifywait
进程,因为其他脚本可以inotifywait
独立使用。因此,使用此命令ps -ef | grep inotifywait
查找正确的 PID 并不是最好的选择,因为您需要一个好的假设哪个inotifywait
进程属于您的脚本。因此,您最终可能会杀死错误的 PID。此外,该命令killall inotifywait
比前一个命令更激进。但是,如果您真的不关心其他系统是否使用 inotifywait,您可以使用激进的命令。
终止inotifywait
每个inotifywait
实例进程的最佳方法
您可以创建一个文件标志来终止特定正在运行的脚本的 inotifywait。以下脚本示例了如何启动 inotify 脚本、停止它,甚至测试它是否正在为该特定 inotify PID 运行。
#!/bin/bash
# inotify-test.sh
test="changes.txt" # Monitoring file
flag="flag.txt" # For stopping, starting event or whatever flag you need
REPORT_FILE="report.txt"
cat /dev/null > $REPORT_FILE
pid="inotify-test.pid"
cat /dev/null > $max_pid
ARGS1="$1"
function start_monitor {
# If file not exist, then write default start
if [ -f "${flag}" ]; then
echo "start" > "${flag}"
fi
# Do not use -q -q (twice), because it will not output anything after do while loop
(echo "$BASHPID" > $pid; exec inotifywait -q $flag $test -e modify -m) |
while read file action
do
process_flag=$(head -1 ${flag})
if [ "${process_flag}" == "stop" ]; then
echo "Process stopped" >> $REPORT_FILE
kill -- -$$
elif [ "${process_flag}" == "sleep" ]; then
echo "Process sleep: $$" >> $REPORT_FILE
sleep 5
# Important, after sleep, must write start to start
echo "start" > "${flag}"
elif [ "${process_flag}" == "start" ]; then
echo "Process is running" >> $REPORT_FILE
# Only run here if flag is start
echo "File: $file, action: $action, date `date`" >> $REPORT_FILE
else
echo "Invalid flag $$" >> $REPORT_FILE
fi
done & # This symbol & is important, it will run this inotify in background
}
if [ "${ARGS1}" == "start" ]; then
start_monitor
fi
if [ "${ARGS1}" == "stop" ]; then
echo "stop" > "${flag}"
fi
if [ "${ARGS1}" == "test" ]; then
echo "sleep" > "${flag}"
fi
您可以从日志文件中观察此操作$REPORT_FILE
tail -f report.txt
要开始监控,您可以使用:
./inotify-test.sh start
要测试脚本是否正在运行 inotifywait,请执行以下命令:
./inotify-test.sh test
因此,要停止 inotify 运行进程,只需运行相同的脚本即可
./inotify-test.sh stop
使用此方法,您不需要知道该 inotifywait 进程的进程 ID 是什么。
它是如何工作的?
您注意到我有 2 个文件需要$flag $test
通过inotifywait
命令进行监控,因此如果我对文件进行更改$flag
,修改事件将立即触发,我可以利用这个机会停止 中的 PID 进程。此外,您可以看到脚本实际上在 处存储inotifywait loop
了一个实际的 pid 。因此,您可以使用这个正确的 pid手动终止该进程。inotifywait
pid="inotify-test.pid"
inotifywait
答案3
这将终止所有实例inotifywait
:
pkill inotifywait
答案4
使用时inotifywait --daemon
您永远不会获得进程的 ID。
如果您像我一样并且不想不加区别地杀死所有 inotifywait 实例,那么您可以改用nohup
and inotifywait --monitor
。
以下是我在 Bash 脚本中使用它的方法。它允许我不干扰其他正在运行的实例inotifywait
:
# Launch with nohup and redirect inputs and outputs
nohup inotifywait --monitor --outfile /out/file </dev/null >/dev/null 2>&1 &
# Gets process ID of last launched process.
_INOTIFYWAIT_PID=$!
# later on ...
# Kill only this instance of 'inotifywait'
kill ${_INOTIFYWAIT_PID}
输入和输出重定向命令(</dev/null >/dev/null 2>&1 &
)来自StackOverflow 上的这个答案