Bash 脚本、监视文件夹、执行命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6475252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash script, watch folder, execute command
提问by ThomasReggi
I am trying to create a bash script with 2 parameters:
我正在尝试使用 2 个参数创建一个 bash 脚本:
- a directory
- a command.
- 一个目录
- 命令。
I want to watch the directory parameter for changes: when something has been changed the script should execute the command.
我想观察目录参数的变化:当某些东西发生变化时,脚本应该执行命令。
I'm running MacOS, not Linux; any pointers or external resources would greatly help as I have see that this is difficult to achieve. Really OI am trying to mimic SASS's watch functionality.
我运行的是 MacOS,而不是 Linux;任何指针或外部资源都会有很大帮助,因为我已经看到这很难实现。真的 OI 试图模仿 SASS 的手表功能。
#!/bin/bash
#./watch.sh $PATH $COMMAND
DIR=
ls -l $DIR > $DIR/.begin
#this does not work
DIFFERENCE=$(diff .begin .end)
if [ $DIFFERENCE = '\n']; then
#files are same
else
fi
ls -l $DIR > $DIR/.end
采纳答案by ThomasReggi
Here's an example of watching a folder for changes and running a the less compiler when one is updated. As a prereq you need npm
and these the module onchange. The node community has a whole bunch of different watch commands (like onchange) I'm not aware of any that are compiled self-contained binaries.
这是一个查看文件夹更改并在更新时运行 less 编译器的示例。作为先决条件,您需要npm
这些模块onchange。节点社区有一大堆不同的监视命令(如 onchange),我不知道有任何编译自包含的二进制文件。
npm install less onchange -g
Then you can use something like:
然后你可以使用类似的东西:
onchange "./stylesheets/*.less" -- lessc main.less > main.css
I prefer a BASH command over the Grunt answerI gave a while back.
回答by Radek
To continuously recursively monitor folder (md5) and execute a command on change:
要连续递归监视文件夹 (md5) 并在更改时执行命令:
daemon() {
chsum1=""
while [[ true ]]
do
chsum2=`find src/ -type f -exec md5 {} \;`
if [[ $chsum1 != $chsum2 ]] ; then
compile
chsum1=$chsum2
fi
sleep 2
done
}
Works on my OS X as I do not have digest
.
在我的 OS X 上工作,因为我没有digest
.
On Linux, you can use md5sum
as a replacement for the md5
command.
在 Linux 上,您可以使用md5sum
该md5
命令的替代品。
回答by Swift
METHOD 1:
方法一:
#!/bin/sh
check() {
dir=""
chsum1=`digest -a md5 $dir | awk '{print }'`
chsum2=$chsum1
while [ $chsum1 -eq $chsum2 ]
do
sleep 10
chsum2=`digest -a md5 $dir | awk '{print }'`
done
eval
}
check $*
This script takes in two parameters [directory, command]. Every 10 seconds the script executes check()
to see it the folder has changed. If not it sleeps and the cycle repeats.
该脚本接受两个参数 [目录、命令]。脚本每 10 秒执行一次check()
以查看文件夹已更改。如果不是,它会休眠并且循环重复。
In the event that the folder has changed, it eval
s your command.
如果文件夹已更改,则eval
是您的命令。
METHOD 2:
Use a cron to monitor the folder.
方法 2:
使用 cron 监视文件夹。
You'll have to install incron:
你必须安装 incron:
sudo apt-get install incron
And then your script will look something like this:
然后你的脚本看起来像这样:
#!/bin/bash
eval
(You won't need to specify the folder since it will be the job of the cron to monitor the specified directory)
(您不需要指定文件夹,因为监视指定目录是 cron 的工作)
A full, working example can be found here:
可以在此处找到完整的工作示例:
回答by Evi1M4chine
I can't believe nobody posted this yet.
我不敢相信还没有人发布这个。
First make sure inotify-tools
are installed.
首先确保inotify-tools
已安装。
Then use them like this:
然后像这样使用它们:
logOfChanges="/tmp/changes.log.csv" # Set your file name here.
# Lock and load
inotifywait -mrcq $DIR > "$logOfChanges" &
IN_PID=$$
# Do your stuff here
...
# Kill and analyze
kill $IN_PID
cat "$logOfChanges" | while read entry; do
# Split your CSV, but beware that file names may contain spaces too.
# Just look up how to parse CSV with bash. :)
path=...
event=...
... # Other stuff like time stamps?
# Depending on the event…
case "$event" in
SOME_EVENT) myHandlingCode path ;;
...
*) myDefaultHandlingCode path ;;
done
Alternatively, using --format
instead of -c
on inotifywait
would be an idea.
或者,使用--format
而不是-c
oninotifywait
将是一个想法。
Just man inotifywait
and man inotifywatch
for more infos.
只是man inotifywait
与man inotifywatch
更多的相关信息。
回答by Devrim
probably the fastest way of doing it.. (on 1G git repo, returns under 1sec.)
可能是最快的方法..(在 1G git repo 上,在 1 秒内返回。)
#!/bin/bash
watch() {
echo watching folder / every secs.
while [[ true ]]
do
files=`find -type f -mtime -s`
if [[ $files == "" ]] ; then
echo "nothing changed"
else
echo changed, $files
fi
sleep
done
}
watch folder 3
回答by John Vargo
In Mac OS X, you can just control-click a folder, then click 'Folder Actions Setup'. This will allow you attach actions to a folder, i.e. scripts to run.
在 Mac OS X 中,您只需按住 Control 键并单击文件夹,然后单击“文件夹操作设置”即可。这将允许您将操作附加到文件夹,即要运行的脚本。
OS X comes with a number of prebuilt scripts, or you can create your own.
OS X 附带了许多预构建的脚本,您也可以创建自己的脚本。
回答by Devonte
#!/bin/bash
# Author: Devonte
# NGINX WATCH DAEMON
# Place file in root of nginx folder /etc/nginx
# This will test your nginx config on any change and
# if there are no problems it will reload your configuration
# USAGE: sh nginx-watch.sh
dir=`dirname find . -type f
`
checksum_initial=`tar -cf - $dir | md5sum | awk '{print }'`
checksum_now=$checksum_initial
# Start nginx
nginx
while true
do
sleep 3
checksum_now=`tar -cf - $dir | md5sum | awk '{print }'`
if [ $checksum_initial != $checksum_now ]; then
echo "[ NGINX ] A configuration file changed. Reloading..."
nginx -t && nginx -s reload;
fi
checksum_initial=$checksum_now
done
回答by swalog
I wrote a general utility called watchfile
for simplifying these kinds of operations.
我编写了一个通用实用程序,watchfile
用于简化这些类型的操作。
It is less powerfull than inotifywatch
, but I prefer a simpler, less verbose utility.
它不如 强大inotifywatch
,但我更喜欢更简单、更简洁的实用程序。
For the desired task, you want to monitor if any files in current directory have been modified. To list all files recursively in the current directory:
对于所需的任务,您希望监视当前目录中的任何文件是否已被修改。递归列出当前目录中的所有文件:
find . -type f -print0 | xargs -0 stat
To output the timestamp information of each of these files:
输出每个文件的时间戳信息:
watchfile -s "find . -type f -print0 | xargs -0 stat" -e CMD
Now, you can monitor this output with the watchfile
utility and execute a command CMD
when this information changes:
现在,您可以使用该watchfile
实用程序监视此输出并CMD
在此信息更改时执行命令:
module.exports = function (grunt) {
grunt.initConfig({
shell: {
run_file:{
command: 'sh ./bash.sh',
options: {
stdout: true
}
}
},
watch: {
run_file: {
files: ["./watchme/*"],
tasks: ["shell:run_file"]
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-shell');
};
回答by ThomasReggi
Almost 3 years later and I'd recommend this grunt based solution.
差不多 3 年后,我推荐这个基于 grunt 的解决方案。
I created a working example here https://github.com/reggi/watch-execute.
我在这里创建了一个工作示例https://github.com/reggi/watch-execute。
Here's the Gruntfile.js
:
这是Gruntfile.js
:
on adding folder items to this_folder after receiving added_items
tell application "Finder"
...
回答by Eric Fortis
Why not using AppleScript
为什么不使用 AppleScript
http://www.tuaw.com/2009/03/26/applescript-exploring-the-power-of-folder-actions-part-iii/
http://www.tuaw.com/2009/03/26/applescript-exploring-the-power-of-folder-actions-part-iii/
##代码##