我希望监视文件中的内容更改,当内容更改时,生成显示新文本的通知。
细节
假设 file( connection.txt
) 只包含单词
"You are connected to the internet"
.
但是,当计算机与互联网断开连接时,文件的内容将更改为"You are now disconnected from the internet"
.
如何监视文件的内容,并且仅当内容发生更改时,才在桌面通知中显示新文本(我使用的是 Manjaro)。
更糟糕的是,该文件每四秒更新一次,通常包含完全相同的文本。
我的研究
我已经搜索过此问题的解决方案但无济于事。我发现了许多监视文件和目录事件更改的示例,例如创建、修改或删除的文件,但没有找到实时监视文件内文本的示例。
如果可能的话,是否有类似的技术来监视命令输出的更改?
答案1
对于一般情况,您希望监视文件,并仅在内容发生更改时发送包含新文件内容的桌面通知,您可以使用inotifywait
(from inotify-tools
) 和-m
,--monitor
选项来无限期执行。
--format "%e"
将仅将事件类型打印到下一个命令。
notify-send
, 从库通知对于桌面通知,仅在文件内容被修改时才用于发送通知。
#!/bin/bash
f="filename"
curr=$(<"$f")
inotifywait -m -e modify "$f" --format "%e" | while read -r event; do
if [ "$event" == "MODIFY" ]; then
prev="$curr"
curr=$(<"$f")
[ "$curr" == "$prev" ] || notify-send "Title" "$curr"
fi
done
对于您的具体情况,如果您的目标是显示带有“您已连接”或“您已断开连接”等文本的桌面通知,我不会监视文件的更改。我会将您在该文件中打印该文本的位置(如您所说,每隔 N 秒)修改为如下所示:
while true; do
prev="$curr"
curr=$( <here you output the new text> )
[ "$curr" == "$prev" ] || notify-send "Title" "$curr"
sleep 4
done
答案2
我想分享一个骨骼代码。您可以扩展这个想法。
#!/bin/bash
# monitor_changes
#
# notifies changes to FILE passed as first parameter $1
# uses tail -1 to return last line of the file
# first run -- save last line on variable old
old=$(tail -1 $1)
# infinite loop
while : ; do
sleep 1
# read again last line
new=$(tail -1 $1)
# this is where the magic should happen
[[ "$old" != "$new" ]] && echo "NOTIFY: $old --> $new"
# save for next round
old=$new
done
答案3
inotify
捕捉(潜在的)变化。仅仅因为文件被修改,并不意味着它被更改。
make
文件更改的行为。它与文件日期一起使用,因此这需要可靠。您还需要一个输出文件,这可以是您在写入屏幕后创建的虚拟文件。
完成第二部分的其他工具:例如,使用文件哈希(而不是日期),如果文件很小,则保留副本并使用cmp
.
使用示例
#!/bin/bash
while true
do
inotify-wait --event modify source-file.txt
make $(basename source-file .txt).stamp
#there is a race hazard here: if the file changes again before we get back to the wait, then it may not be picked up.
done
# A make file template
%.stamp: %.txt
«tab» do_it $<
«tab» touch $@
将 «tab» 替换为选项卡。替换do_it
为执行此操作的代码。将$<
替换为源文件名。