【问题标题】:Folder Watcher bash script: also check for subfoldersFolder Watcher bash 脚本:还检查子文件夹
【发布时间】:2013-09-06 21:21:13
【问题描述】:

编辑:

我已经改进了用户 konsolebox 的这个“FolderWatcher 脚本”(来自下面的答案:https://stackoverflow.com/a/18597233/2095175) 我添加了这些行以自动移动系统上正确文件夹中的每种文件(例如 /Docs 文件夹中的 pdf、/Picture 中的图像和 /Videos 中的视频文件)

extension=${ADDED##*.}
if [ "$extension" = "xz" ] || [ "$extension" = "zip" ] || [ "$extension" = "gz" ] || [ "$extension" = "bz2" ] || [ "$extension" = "7z" ]; then
open $ADDED
fi
if [ "$extension" = "pdf" ] || [ "$extension" = "txt" ] || [ "$extension" = "odt" ] || [ "$extension" = "doc" ] ; then
mv "$ADDED" /boot/home/Docs
alert --idea " $ADDED moved to /boot/home/Docs"
open /boot/home/Docs
fi
if [ "$extension" = "jpg" ] || [ "$extension" = "png" ] || [ "$extension" = "gif" ]; then
mv "$ADDED" /boot/home/Media/Images
alert --idea " $ADDED moved to /boot/home/Media/Images"
open /boot/home/Media/Images
fi
if [ "$extension" = "flv" ] || [ "$extension" = "avi" ] || [ "$extension" = "mp4" ] || [ "$extension" = "mpg" ]; then
mv "$ADDED" /boot/home/Media/Video
alert --idea " $ADDED moved to /boot/home/Media/Video"
open /boot/home/Media/Video
fi

原始问题:

我有以下脚本不断检查文件夹的内容,并在插入新文件和/或删除新文件时提醒我。按预期完美运行。但不检查主文件夹中的子文件夹( folder=$(cat /boot/home/FolderWatcher_pref.txt) ) 例如,如果我从主文件夹插入/删除文件,我会收到警报,但如果我在“$folder”的子文件夹中插入/删除文件,脚本将无法提醒我。我可以在此脚本中更改或添加什么来满足此需求?

我在 Haiku OS 上,所以像“alert”这样的命令是 Haiku 特有的。

#!/bin/bash 猫 /dev/null > $difffile1 猫 /dev/null > $difffile2 #查看路径在文本文件中设置,我可以通过文件面板更改以选择任何文件夹 文件夹=$(cat /boot/home/FolderWatcher_pref.txt) tstamp=$(stat --print "%Y" "$folder") 虽然是真的;做 prev=$(ls "$folder" | tr '\n' '\n' > /tmp/prev.txt) 睡觉 5 if [[ "$folder" == "$folder" && $tstamp -lt $(stat --print "%Y" "$folder") ]];然后 after=$(ls "$folder" | tr '\n' '\n' > /tmp/after.txt) 差异1=$(comm -2 -3 "/tmp/after.txt" "/tmp/prev.txt">/tmp/Diff.txt) 添加=$(cat /boot/common/cache/tmp/Diff.txt) 差异2=$(comm -2 -3 "/tmp/prev.txt" "/tmp/after.txt">/tmp/Diff2.txt) 丢失=$(cat /boot/common/cache/tmp/Diff2.txt) difffile1=/tmp/Diff.txt difffile2=/tmp/Diff2.txt FILESIZE2=$(stat -c%s "$difffile2") 如果 [ "$FILESIZE2" == 0 ] 然后 丢失=没有 菲 FILESIZE1=$(stat -c%s "$difffile1") 如果 [ "$FILESIZE1" == 0 ] 然后 添加=无 菲 lost2=$(cat /boot/common/cache/tmp/Diff2.txt) 警报 --idea "$文件夹: $已添加 *插入*。 $丢失 *删除*。"; echo "$lost2" >>$folder/Removed.txt tstamp=$(stat --print "%Y" "$folder") 猫 /dev/null > $difffile1 猫 /dev/null > $difffile2 别的 睡觉 3; 菲 完毕

【问题讨论】:

  • 这一行有点奇怪:prev=$(ls "$folder" | tr '\n' '\n' > /tmp/prev.txt)。顺便说一句有趣的脚本..
  • 这一行将文件夹的内容打印到一个临时文本文件中。然后与 after=$(ls "$folder" | tr '\n' '\n' > /tmp/after.txt) 进行比较。到 diff.txt 以获取添加或删除的文件的名称(使用 diff2.txt)
  • @konsolebox 看看我的问题:我对你的脚本做了一些改进:让我知道你的想法:-)
  • 由于 extglob 已经启用,您的比较像 [ "$extension" = "xz" ] || [ "$extension" = "zip" ] || [ "$extension" = "gz" ] || [ "$extension" = "bz2" ] || [ "$extension" = "7z" ]; then 可以简化为 [[ $extension == @(xz|zip|gz|bz2|7z) ]]。您也可以通过 shopt -s nocaseglob 忽略此情况。最好引用你的变量:open "$ADDED"。我认为一切都很好。
  • @konsolebox "shopt -s nocaseglob" 需要什么?

标签: bash file directory


【解决方案1】:

你想增加这条线:

prev=$(ls "$folder" | tr '\n' '\n'  > /tmp/prev.txt)

类似于:

prev=$(ls "$folder"/* | tr '\n' '\n'  > /tmp/prev.txt)

【讨论】:

  • 实际上他甚至不需要使用变量prev,因为脚本会比较文件。
  • 不起作用..无论如何我还必须添加“|排序|”。另一个建议?
  • 那么使用find 怎么样?始终可以将其文件名输出(使用-print)通过管道传输到xargs
  • 你能举一个实际的例子吗,保罗?谢谢。
【解决方案2】:

为什么不能使用 inotifywaitinotifywatch ?您可以使用-r 标志使其递归。 看看inotify-tools
您可能也对incron 感兴趣。

【讨论】:

  • 在 Haiku 上,我们没有 inotify-tools。也不是 incron
  • @Giova84 哦,我明白了。对不起。我不会删除这个答案,以防其他人发现这个问题。
  • 别担心,事实上可能对其他人有用:-)
【解决方案3】:

我最终进行了自己的修改,但这个可以工作并且不再使用临时文件。它使用findprocess substitution

#!/bin/bash

[ -n "$BASH_VERSION" ] && [[ BASH_VERSINFO -ge 3 ]] || {
    echo "You need bash version 3.0 or newer to run this script." >&2
    exit 1
}

shopt -s extglob

FOLDER=$(</boot/home/FolderWatcher_pref.txt)
REMOVED_LOG="$FOLDER/Removed.txt"  ## It's better to place this somewhere not in "$FOLDER" to not confuse timestamps everytime it is updated.

if [[ ! -d $FOLDER ]]; then
    echo "Directory does not exist: $FOLDER" >&2
elif read TIMESTAMP < <(exec find "$FOLDER" -type d -printf "%T@\n" | cut -f 1 -d . | sort -nr); [[ $TIMESTAMP != +([[:digit:]]) ]]; then
    echo "Unable to get timestamp of directory: $FOLDER" >&2
else
    STATE=$(exec find "$FOLDER" -mindepth 1 | sort)

    for (( ;; )); do
        sleep 5

        if [[ -d $FOLDER ]] && read NEWTIMESTAMP < <(exec find "$FOLDER" -type d -printf "%T@\n" | cut -f 1 -d . | sort -nr) && [[ NEWTIMESTAMP -gt TIMESTAMP ]]; then
            NEWSTATE=$(exec find "$FOLDER" -mindepth 1 | sort)

            ADDED=$(comm -2 -3 <(echo "$NEWSTATE") <(echo "$STATE"))
            [[ -z $ADDED ]] && ADDED='nothing'

            LOST=$(comm -2 -3 <(echo "$STATE") <(echo "$NEWSTATE"))
            LOST_ORIG=$LOST
            [[ -z $LOST ]] && LOST='nothing'

            alert --idea "$FOLDER:

$ADDED
*INSERTED*.

$LOST
*REMOVED*."

            [[ -n $LOST_ORIG ]] && echo "$LOST_ORIG" >> "$REMOVED_LOG"

            read TIMESTAMP < <(exec find "$FOLDER" -type d -printf "%T@\n" | cut -f 1 -d . | sort -nr) && [[ TIMESTAMP -ge NEWTIMESTAMP ]] || TIMESTAMP=$NEWTIMESTAMP
            STATE=$NEWSTATE
        fi
    done
fi

【讨论】:

  • 它有效。除了如果我从任何子文件夹中删除文件,我不会收到警报。如果我从主文件夹中删除文件,我只会收到删除文件的警报。无论如何,谢谢你,这就是我想要的!
  • @Giova84 我希望它也能显示从子文件夹中删除的文件,因为find 是递归的。它不这样做吗?
  • 我还注意到:如果我从另一个文件夹(不是 $folder)中删除或添加子文件夹中的文件,我不会收到警报。仅当我将文件从 $folder 中的子文件夹中移动时,我才会收到子文件夹的警报。
  • @Giova84 我更新了。我希望它现在可以工作了 :) 如果您再次发现有问题,请告诉我。
  • 现在它就像一个魅力!我对我无法投票给你的答案这一事实感到难过,因为我需要 15 声望!你很温柔:-)
猜你喜欢
  • 2016-02-10
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
相关资源
最近更新 更多