我正在尝试编写一个脚本,该脚本将从特定目录中获取文件并将其复制到Linux redhat服务器上的另一个目录中。有问题的文件名称为abc ###。doc,其中的“#”代表数字。每当在该目录中移动或创建一个新文件并使用该文件名时,我都希望该文件立即复制到另一个目录。例如,假设目录已包含以下文件:
abc001.doc
abc002.doc
abc003.doc
然后添加了一个新文件,所以现在看起来像这样:
abc001.doc
abc002.doc
abc003.doc
abc004.doc
我只希望复制abc004.doc文件。然后,如果添加了另外两个文件,例如abc005.doc和abc006.doc,则它们也将被复制,而不会复制前四个文件。
当试图找到解决方案时,我首先想到的是 inotifywait 。但是,这需要我们在Linux服务器上安装它。不幸的是,由于我们环境中的安全设置,我们无法做到这一点。
我还看到了一种使用python的有趣方法:https://askubuntu.com/questions/893019/monitor-folder-and-run-command-if-there-is-a-file-there。但是,这样做的问题是它会在其中查找并移动所有文件。对于我的特定问题,文件不会从该目录移动,而是会被复制。因此,它将以abc ###。doc格式复制所有文件,而不仅仅是新文件。
我唯一想做的另一件事是,也许有一个已经处理过的文件名列表,并随着新文件的进入和处理而添加到文件名列表中。但是肯定有一种更优雅的方式来解决我的问题...
Linux上是否有其他我可以用来解决此问题的工具?
答案 0 :(得分:0)
inotify在大多数linux系统上是非常标准的。该接口由内核提供。如果系统上有标准的C编译器,则可以非常轻松地构建工具。许多解释器(perl,python,php-cli ...)和Mono也具有接口。从外壳创建inotify监视表似乎没有直接接口。
如果您没有使用inotify的工具,则别无选择,只能进行轮询。可以容忍的延迟时间越长越好。您可以使用“标准工具” stat 来查看目录的最后修改时间并进行跟踪,也可以使用“标准工具” 查找来查看内容自文件更改以来一直更改文件。
inotify当然是首选,因为它只会使用read(2)阻止脚本,直到进行更改并立即采取措施。在我知道可用的工具之前,我无法为您提供使用此工具的解决方案。
一种非创新的解决方案如下:
#!/bin/bash
export SourceDir="/whatever"
export DestDir="/whatever else"
# assume that everything is in sync as of now
# we could save/load last_mtime in a file if this is a bad assumption
last_mtime=`stat "${SourceDir}" -c %Y`
while true; do
new_mtime=`stat "${SourceDir}" -c %Y`
if (( ${new_mtime} > ${last_mtime} )); then
ls "${SourceDir}" | while read filename ; do
if [ -f "${filename}" ]; then
file_mtime=`stat "${filename}" -c %Y`
if (( ${file_mtime} > ${last_mtime} )); then
cp "${SourceDir}/${filename}" "${DestDir}"
fi
fi
done
export last_mtime=${new_mtime}
fi
# wait 5 seconds before we check again
sleep 5
done
您将不得不在后台不断运行脚本(可能以nohup开头)。如果您可以忍受长达1分钟或更长时间的延迟,则可以剥离while循环并休眠并使用cron运行它(假设您的“标准工具”中包含cron),甚至可以仅使用cron和rsync(假设您具有rsync),并且没有多余的脚本。