我试图让inotifywait
脚本在看到监视目录中出现 close_write 标志时对文件和文件夹采取不同的操作,但似乎无法使检查工作。
在其他脚本中,我一直使用这些类型的检查,它们只是工作,但似乎有些东西inotifywait
我还没有掌握。
这是当前形式的脚本:
#!/bin/bash
dir1=/sambashares
while true; do
inotifywait -r -e close_write "$dir1" | while read f; do
#debug
echo $f
#Is it a directory?
if [[ -d "${f}" ]]; then
#debug
echo "New directory called ${f} detected"
chown -R jake:jake $f
chmod -R 775 $f
cp -R $f /media/lacie/Film
fi
#Is it a file?
if [[ -f "${f}" ]]; then
#debug
echo "New file called ${f} detected"
chown jake:jake $f
chmod 775 $f
cp $f /media/lacie/Film
fi
done
done
如果我在终端中运行它来查看发生了什么,我得到的只是检测到 close_write 的确认,然后是“设置监视”,没有任何其他消息或任何其他代码被触发,甚至没有直接调试回显以下:
while read f; do
:-(
我在 Ubuntu 服务器 12.04 LTS 64 位上运行它。
$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
$ dpkg -l | grep inotify
ii inotify-tools 3.13-3
ii libinotifytools0 3.13-3
ii python-pyinotify 0.9.2-1
$ python --version
Python 2.7.3
答案1
以下对我有用:
例子
inotifywait
下面显示了使用与您自己的方法类似的方法的示例。
$ inotifywait -r -e close_write "somedir" | while read f; do echo "$f hi";done
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
然后我进入目录somedir
并触摸一个文件,touch afile
.这会导致inotifywait
窗口中发生这种情况:
somedir/ CLOSE_WRITE,CLOSE afile hi
笔记:要获得所有输出,inotifywait
您可以稍微修改您的示例:
$ inotifywait -r -e close_write "somedir" 2>&1 | \
while read f; do echo "$f | hi";done
Setting up watches. Beware: since -r was given, this may take a while! | hi
Watches established. | hi
再次使用命令触摸文件,touch afile
我现在看到了该事件:
somedir/ CLOSE_WRITE,CLOSE afile | hi
有关演示如何使用的另一个示例,inotifywait
请查看我在回答此问答时所展示的示例,标题为:自动检测文件何时达到大小限制。
你的问题
我认为您遇到的问题的一部分在于您假设返回的输出inotifywait
只是文件的名称,但从上述示例来看,它显然不是。
所以这些if
语句永远不会成功:
if [[ -d "${f}" ]]; then
and
if [[ -f "${f}" ]]; then
在开发此类 Bash 脚本时,通过顶部的此命令启用调试消息通常很有帮助:
set -x
您可以通过以下方式禁用它:
set +x
您可以使用这些消息来包装代码部分以打开/关闭它。
set -x
...code...
set +x
答案2
感谢 slm 提供的信息,让它正常工作:-)
#!/bin/bash
# Written by Jan Duprez and licensed as
# do whatever you want with this but don't come whining
# if you somehow manage to trash your system with it.
# You pressed the buttons, remember?
# This script uses inotifywait to watch a directory and copies
# files or directories moved into it to another folder.
# The commandline parameters are:
# 1 - Directory to watch
# 2 - Directory where new file/folder is copied to
# 3 - UID to use to chmod the file/folder in BOTH dirs
# 4 - GID to use to chmod the file/folder in BOTH dirs
# 5 - permissions to set for the new file/folder in BOTH dirs
dir1=$1
dir2=$2
user=$3
group=$4
perms=$5
# Check if commandline parameters are all there, show reminder if not
if [[ -z $dir1 || -z $dir2 || -z $user || -z $group || -z $perms ]];
then
echo -e "Please provide a source dir as 1st parameter"
echo -e "Please provide a dest dir as 2nd parameter"
echo -e "Please provide a UID as 3rd parameter"
echo -e "Please provide a GID as 4th parameter"
echo -e "Please provide a file permission string (ex 755) as 5th parameter"
exit
fi
# Good to go, start watching
while true; do
#add -e close_write and -e create for testing
inotifywait -r -e move "$dir1" | while read f; do
#Get part after inotify triggers with awk, remove leading spaces with sed
new=`echo $f | awk '{$1=$2=""; print $0}' | sed 's/^ *//'`
#And the preconstruded full path to avoid ugly buggery between the [[ ]] test
test=$dir1$new
if [[ -d "${test}" ]] ; then
chown -R $user:$group "$dir1$new"
chmod -R $perms "$dir1$new"
cp -R "$dir1$new" "$dir2"
chown -R $user:$group "$dir2$new"
fi
if [[ -f "${test}" ]] ; then
chown $user:$group "$dir1$new"
chmod $perms "$dir1$new"
cp "$dir1$new" "$dir2"
chown $user:$group "$dir2$new"
fi
done
done