文件复制到目录时自动运行命令

文件复制到目录时自动运行命令

我有两个名为:A 和 B 的文件夹,位于同一台计算机上的不同路径中。当我将任何新文件添加到文件夹 A 时,我想自动将其复制到文件夹 B。

我的文件夹:

/auto/std1/nat1/A
/auto/std2/nat2/B

我目前复制文件的操作:

cp -r A B

但我希望这个过程在后台自动运行AB.

添加了疑问/问题

复制文件时,我希望对某些文件类型执行特定操作,例如:当我zip在文件夹中有一个文件时A,我希望它自动复制到unzip文件夹中的该文件B

这是在 CentOS 7` 系统上。

答案1

rsync根据您的奖励问题,在我在下面提供的 shell 脚本中的命令下方添加以下行。我在评论中写了这个,但我将在这里正式将其添加到我的答案中:

    find /auto/std2/nat2/B -name '*.zip' -exec sh -c 'unzip -d `dirname {}` {}' ';'

rsync这将处理从文件夹/auto/std2/nat2/A复制到的所有 zip 文件的解压/auto/std2/nat2/B



如果你已经rsync安装了,为什么不直接执行 cron 并管理rsync文件镜像呢?

创建脚本myrsyncscript.sh

不要忘记使其可执行:chmod 700 myrsyncscript.sh

#!/bin/sh

LOCKFILE=/tmp/.hiddenrsync.lock

if [ -e $LOCKFILE ]
        then
        echo "Lockfile exists, process currently running."
        echo "If no processes exist, remove $LOCKFILE to clear."
        echo "Exiting..."
#        mailx -s "Rsync Lock - Lock File found" [email protected] <<+
#Lockfile exists, process currently running.
#If no processes exist, remove $LOCKFILE to clear.
#+
        exit
fi

touch $LOCKFILE
timestamp=`date +%Y-%m-%d::%H:%M:%s`
echo "Process started at: $timestamp" >> $LOCKFILE

## Run Rsync if no Lockfile
rsync -a --no-compress /auto/std1/nat1/A /auto/std2/nat2/B


echo "Task Finished, removing lock file now at `date +%Y-%m-%d::%H:%M:%s`"
rm $LOCKFILE

选项细目:

-a is for archive, which preserves ownership, permissions etc.
--no-compress as there's no lack of bandwidth between local devices

您可能会考虑的其他选项man rsync:

--忽略现有的

跳过更新接收器上存在的文件

- 更新

这会强制 rsync 跳过目标上存在且修改时间比源文件更新的任何文件。 (如果现有目标文件的修改时间等于源文件的修改时间,并且大小不同,则它将被更新。)请注意,这不会影响符号链接或其他特殊文件的复制。此外,发送者和接收者之间的文件格式差异始终被认为对于更新来说足够重要,无论对象上的日期是什么。换句话说,如果源有一个目录,而目标有一个文件,则无论时间戳如何,传输都会发生。

此选项是传输规则,而不是排除,因此它不会影响进入文件列表的数据,因此不会影响删除。它只是限制接收者请求传输的文件。

像这样将其添加到 cron 中,并将频率设置为您觉得最舒服的值:

打开 croncrontab -e并添加以下内容:

### Every 5 minutes
*/5 * * * * /path/to/my/script/myrsyncscript.sh > /path/to/my/logfile 2>&1 

# * * * * *  command to execute
 # │ │ │ │ │
 # │ │ │ │ │
 # │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
 # │ │ │ └────────── month (1 - 12)
 # │ │ └─────────────── day of month (1 - 31)
 # │ └──────────────────── hour (0 - 23)
 # └───────────────────────── min (0 - 59)

答案2

使用 inotifywait 和有节奏的事件响应来实现 @Izkata 的建议,以将 rsyncs 保持在每 5 分钟最多 1 次,同时仍然快速响应初始更改:

#!/bin/sh
# usage: whateveryouwanttotcallthis "$directorytowatch" rsync args here

cd "$1" || { echo "${0##*/}: can't cd to $1"; exit 1; }
shift
rsync -nq "$@" || { echo "rsync doesn't like your $# arguments $@"; exit 1; }

notbefore=0
watchlock=.lock.inotifywait
rsynclock=.lock.rsync-pending

mkdir $watchlock ||
       { echo "${0##*/}: already running, rmdir '$PWD/$watchlock' if kill -9 took it out"
         exit 1;
       }
trap "rmdir '$watchlock'" 0 1 2 3 15

inotifywait -m -e close-write . |    # maybe also add move
        while read; do
                mkdir $rsynclock 2>&- || continue
                schedule=$(( notbefore <= (now=`date +%s`+2) ? (now+2)
                                                           : (notbefore) ))
                notbefore=$((schedule+300))
                ( ( trap "rmdir '$rsynclock'" 0 1 2 3 15
                    sleep $(( schedule-now ))
                  )
                  # substitute your payload here
                  rsync --exclude='.lock.*' "$@" \
                          || echo ssia | mail -s "${0##*/} '$PWD' rsync failed" opswatch
                ) &
        done

两秒的延迟既有助于批量处理小突发,又允许有时间在写入完成时重命名某些事情。也许15秒会更好。

无法在 Windows atm 上进行测试,我希望并相信它至少非常接近。

答案3

您可以使用 DevNull 建议定期进行 rsync 的内容。我个人会使用inotify。这是一个很棒的工具,您可以监视文件夹。它会设置监视点,并在文件系统发生更改时通知您。然后,您可以根据 中的触发器触发 rsync inotify

对于你最后谈到的具体情况,你可以使用 inotify 的触发器来查看发生了什么变化,然后编写一个简单的 bash 脚本来检查它是否是已添加到文件夹 A 的 zip 文件以及是否是,然后您可以将其解压缩到文件夹 B(或您想要执行的任何其他操作),而不是仅复制 zip。

相关内容