Answers:
您应该考虑使用inotifywait
,例如:
inotifywait -m /path -e create -e moved_to |
while read path action file; do
echo "The file '$file' appeared in directory '$path' via '$action'"
# do something with the file
done
在Ubuntu中inotifywait
是由inotify-tools
软件包提供的。从3.13版本开始(Ubuntu 12.04中当前使用)inotifywait
将包含不带-f选项的文件名。较旧的版本可能需要强制执行。需要注意的重要一点是,-e
to选项inotifywait
是进行事件过滤的最佳方法。同样,您的read
命令可以将位置输出分配给多个变量,您可以选择使用或忽略这些变量。无需使用grep / sed / awk预处理输出。
inotifywait
正是我想要的。
The '--filename' option no longer exists. The option it enabled in earlier versions of inotifywait is now turned on by default.
So,那么您只需要做的inotifywait -m /path -e create |
就是尝试编辑此答案。
fswatch
。我没有写它,但是它是开源的,我使用它。
我更喜欢incron
,因为它更易于管理。本质上,它是一种利用服务,inotify
您可以设置配置以根据文件更改操作采取措施。
例如:
<directory> <file change mask> <command or action> options
/var/www/html IN_CREATE /root/scripts/backup.sh
您可以在此处看到完整的示例:http : //www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/
我刚做完这个,并没有看到任何大的问题,除了两次检查之间丢失文件的几率很小。
while true
do
touch ./lastwatch
sleep 10
find /YOUR/WATCH/PATH -cnewer ./lastwatch -exec SOMECOMMAND {} \;
done
如果您的文件处理时间不太长,则不应错过任何新文件。您还可以为活动设置背景……这不是防弹的,但是在没有inotify之类的外部工具的情况下,它可以达到某些目的。
inotify
没有可用的最佳解决方案。我-type f
只添加过滤出文件。否则,该文件夹也将被返回。
-f filename
是的- 选项很棒。因此,剩下的唯一问题是如何使它在重新启动时启动。我将在我的太阳能发电厂中使用它,os.system("ssh me@mysystem ' ( touch /home/me/alarms/low24 ) '")
因此创建此文件将使主计算机使用espeak
并宣布低电压。它已经给我发送了一封电子邮件,但是由于我的系统已经在最忙的时候说了时间,所以剩下的时间都包含了。 askubuntu.com/questions/977613/...
您可以watch
在脚本中使用
watch -n 0.1 ls <your_folder>
监视您的文件夹并每隔0.1秒列出其中的所有内容
退税
不是实时的,因此,如果在不到0.1秒的时间内创建和删除文件,则此操作将无效,watch
仅支持最少0.1秒。
我假设目标文件夹(isempty
为方便起见,我将其称为)是空的,并且您正在等待将一个或多个文件放到那里。
您可以使用以下命令:
ls -1A isempty | wc -l
只是检查文件夹是否仍然为空,实际上,如果没有新文件(因此isempty
文件夹仍然为空),它将返回0;或者,另一方面,它将返回大于0的值(实际上是数字)文件夹中当前文件的数量)。
那就是说愚蠢的if / then测试可以完成其余的工作:
if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi
当然,该do_something
功能将必须处理文件isempty
夹中的文件,然后在处理后将其从文件夹本身中删除。
在crontab中添加如下所示的一行将每分钟运行一次检查,并且do_something
如果该文件夹当然不为空,则将触发操作:
* * * * * if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi
如果要检测新文件,请对其进行处理,最后删除继续处理的文件,可以使用systemd.path。此方法基于inotify。有一个DirectoryNotEmpty选项,因此systemd可以在检测到目录中的任何文件时始终运行脚本。您必须记住,仅当您可以删除已处理的文件并且脚本将目录留为空白时,它才有效。
首先准备mymonitor.service文件
[Unit]
Description=Start the script
[Service]
Type=oneshot
ExecStart=/path/to/your/script
接下来转到mymonitor.path定义路径
[Unit]
Description= Triggers the service
[Path]
DirectoryNotEmpty=/path/to/monitor
[Install]
WantedBy=multi-user.target
如果.path文件的名称与服务的名称相同,则无需在.path文件中指定服务名称。
它基于监视虚拟文件的访问
entr
使用entr
是执行此操作的新方法(它是跨平台的)。注意entr
不使用轮询,因此与许多替代方法相比,它具有巨大的优势。
用于
kqueue(2)
或inotify(7)
避免轮询。entr
编写该软件是为了使快速的反馈和自动化的测试自然而自然地完成。
在BSD上,它使用 pledge(2)
您可以使用安装
apt-get install entr
dnf install entr
您可以使用以下方式跟踪目录以查找新添加的内容
while $(true); do
# echo ./my_watch_dir | entr -dnr echo "Running trigger..."
echo ./my_watch_dir | entr -dnr ##MY COMMAND##
done;
选项说明(来自文档),
-d
跟踪作为输入提供的常规文件目录,如果添加新文件,则退出。此选项还允许显式指定目录。名称以“。”开头的文件。被忽略。-n
在非交互模式下运行。在此模式下,entr不会尝试从TTY读取或更改其属性。-r
重新加载一个持久的子进程。与标准操作模式一样,在处理文件系统或键盘事件之前,不会再次执行终止的实用程序。SIGTERM
用于在重新启动实用程序之前将其终止。创建了一个进程组以防止Shell脚本屏蔽信号。entr
等待实用程序退出以确保已关闭套接字等资源。TTY的控制权不会转移到子进程中。
以下是我测试过的Stackoverflow示例的精简版本,并将其合并到需要监视特定目录的项目中。
Var_dir="${1:-/tmp}"
Var_diff_sleep="${2:-120}"
Var_diff_opts="--suppress-common-lines"
Func_parse_diff(){
_added="$(grep -E '>' <<<"${@}")"
if [ "${#_added}" != "0" ]; then
mapfile -t _added_list <<<"${_added//> /}"
_let _index=0
until [ "${#_added_list[@]}" = "${_index}" ]; do
_path_to_check="${Var_dir}/${_added_list[${_index}]}"
if [ -f "${_path_to_check}" ]; then
echo "# File: ${_path_to_check}"
elif [ -d "${_path_to_check}" ]; then
echo "# Directory: ${_path_to_check}"
if [ -p "${_path_to_check}" ]; then
echo "# Pipe: ${_path_to_check}"
fi
let _index++
done
unset _index
fi
}
Func_watch_bulk_dir(){
_current_listing=""
while [ -d "${Var_dir}" ]; do
_new_listing="$(ls "${Var_dir}")"
_diff_listing="$(diff ${Var_dec_diff_opts} <(${Var_echo} "${_current_listing}") <(${Var_echo} "${_new_listing}"))"
if [ "${_diff_listing}" != "0" ]; then
Func_parse_diff "${_diff_listing}"
fi
_current_listing="${_new_listing}"
sleep ${Var_diff_sleep}
done
}