使用示例

使用示例

我希望监视文件中的内容更改,当内容更改时,生成显示新文本的通知。

细节

假设 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为执行此操作的代码。将$<替换为源文件名。

相关内容