Is there a program that will automatically re-run, eg, make, when files are modified?
For example, when I'm writing sphinx documentation, it would be nice if make html was run automatically each time I edit any relevant files.
For simple things, rerun could be a good fit: http://pypi.python.org/pypi/rerun
"Command-line executable Python script to re-run the given command every time files are modified in the current directory or its subdirectories."
It requires a Python interpreter, but does not care if your command or files are written in Python.
Usage
rerun [--help|-h] [--verbose|-v] [--ignore|-i=<file>] [--version] <command>
Where:
<command> Command to execute
--help|-h Show this help message and exit.
--ignore|-i=<file> File or directory to ignore. Any directories of the
given name (and their subdirs) are excluded from the
search for changed files. Any modification to files of
the given name are ignored. The given value is
compared to basenames, so for example, "--ignore=def"
will skip the contents of directory "./abc/def/" and
will ignore file "./ghi/def". Can be specified multiple
times.
--verbose|-v Display the names of changed files before the command
output.
--version Show version number and exit.
In Linux, you can use this command line:
while true; do inotifywait -e close_write *.py; make; done
Uses standard system command inotifywait, if not available, install with something like:
sudo apt install inotify-tools
Well, since make will not do anything if nothing has changed, how about
while true; do sleep 60; make html; done
or the equivalent in your shell of choice? I don't think the usual file system layers are event-driven in such a way that they will you notify you of file changes without doing some similar themselves, but it's possibly DBUS can do that sort of stuff.
You could use inotifywait in a loop: https://github.com/rvoicilas/inotify-tools/wiki/#info
As per answer https://stackoverflow.com/a/22907316/71522 watchman seems to work very well:
$ watchman-make -p '*.c' 'Makefile' -t all
Will re-run make all each time any *.c or Makefile file changes.
It can be installed with:
$ brew install watchman
You could use incron: http://inotify.aiken.cz/?section=incron&page=about&lang=en
This question was also asked here: https://superuser.com/questions/181517/how-to-execute-a-command-whenever-a-file-changes/
You could try reflex
# Rerun make whenever a .c file changes
reflex -r '\.c$' make
Related
I have in my $PATH my own path to my scripts.
I do that adding on my .bashrc
PATH=$PATH:~/home/user/myownscripts
In that directory I have two scripts, but only can use one of them, the first one I did create. And if created another script doesn't work neither.
Only can call the first script created.
The ls command return the following output
first_script second_script third_script
And first_script is bold and green
Why? and how fix this problem?
The second and third scripts are not executable. Use ls -l (provides more details about the files) to see the permissions of the files and run the following command to make these scripts executable.
chmod +x second_script third_script
If you run ls -l again, you should notice that they now have the x bit set in their file permissions.
This is a basic and fundamental aspect to Unix systems and I’d suggest that you read a book or tutorial on shell programming on a Unix-like system.
I have script that does a bunch of stuff. It sources a bunch of functions that are in the directory the script is being run from. i.e.
/home/me/script.sh
/home/me/function1
/home/me/function2
If I cd into /home/me and run ./script.sh everything works fine. The functions are sourced and do what needs to be done.
However, if I try to run this as a cron job, it will run up until the point I am trying to source the functions, and then it just stops and the process is terminated (if I run it directly from the directory, at least I get some errors).
Like wise, if I try to run this from another directory, I get a bunch of errors. e.g.
cd /opt/
/home/me/script.sh
function1: command not found
function2: command not found
I'm sure this has something to do with environmental variables, but I have no idea which ones. I have tried setting (in crontab):
PATH=/home/me
SHELL=/bin/bash
But that doesn't work either. Any help is appreciated. I don't want to hard code in the paths to the functions, and instead make them relative to the path the script is in (preferably the same dir).
Please let me know if you need any more information.
You are most probably aware of this, but just to be clear: A shell function does not have a path. They just need to be loaded into the current shell by sourcing the script that contains them:
source /path/to/functions
or
cd /path/to/functions
source functions
If you are talking about shell programs (scripts) instead, then you need to account for the fact that on Unix-like OS, the current directory is never in the PATH by default:
/path/to/functions/function1
or
cd /path/to/functions
./function1
You tagged your question Bash, but note that to be POSIX-compatible (e.g. if using sh), you have to use the . keyword (instead of either . or source on Bash) and the same restrictions regarding the PATH as for command execution apply, see dot:
. ./function1
I want to watch a folder on my Mac and then execute a bash script, passing it the name of whatever file/folder was just moved into or created in the watched directory.
fswatch
fswatch is a small program using the Mac OS X FSEvents API to monitor a directory.
When an event about any change to that directory is received, the specified
shell command is executed by /bin/bash
If you're on GNU/Linux,
inotifywatch (part of the
inotify-tools package on most distributions) provides similar
functionality.
Update: fswatch can now be used across many platforms including BSD, Debian, and Windows.
Syntax / A Simple Example
The new way that can watch multiple paths - for versions 1.x and higher:
fswatch -o ~/path/to/watch | xargs -n1 -I{} ~/script/to/run/when/files/change.sh
Note: The number output by -o will get added to the end of the xargs command if not for the -I{}. If you do choose to use that number, place {} anywhere in your command.
The older way for versions 0.x:
fswatch ~/path/to/watch ~/script/to/run/when/files/change.sh
Installation with Homebrew
As of 9/12/13 it was added back in to homebrew - yay! So, update your formula list (brew update) and then all you need to do is:
brew install fswatch
Installation without Homebrew
Type these commands in Terminal.app
cd /tmp
git clone https://github.com/alandipert/fswatch
cd fswatch/
make
cp fswatch /usr/local/bin/fswatch
If you don't have a c compiler on your system you may need to install Xcode or Xcode command line tools - both free. However, if that is the case, you should probably just check out homebrew.
Additional Options for fswatch version 1.x
Usage:
fswatch [OPTION] ... path ...
Options:
-0, --print0 Use the ASCII NUL character (0) as line separator.
-1, --one-event Exit fsw after the first set of events is received.
-e, --exclude=REGEX Exclude paths matching REGEX.
-E, --extended Use exended regular expressions.
-f, --format-time Print the event time using the specified format.
-h, --help Show this message.
-i, --insensitive Use case insensitive regular expressions.
-k, --kqueue Use the kqueue monitor.
-l, --latency=DOUBLE Set the latency.
-L, --follow-links Follow symbolic links.
-n, --numeric Print a numeric event mask.
-o, --one-per-batch Print a single message with the number of change events.
in the current batch.
-p, --poll Use the poll monitor.
-r, --recursive Recurse subdirectories.
-t, --timestamp Print the event timestamp.
-u, --utc-time Print the event time as UTC time.
-v, --verbose Print verbose output.
-x, --event-flags Print the event flags.
See the man page for more information.
You can use launchd for that purpose. Launchd can be configured to automatically launch a program when a file path is modified.
For example the following launchd config plist will launch the program /usr/bin/logger when the desktop folder of my user account is modified:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>logger</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/logger</string>
<string>path modified</string>
</array>
<key>WatchPaths</key>
<array>
<string>/Users/sakra/Desktop/</string>
</array>
</dict>
</plist>
To activate the config plist save it to the LaunchAgents folder in your Library folder as "logger.plist".
From the shell you can then use the command launchctl to activate the logger.plist by running:
$ launchctl load ~/Library/LaunchAgents/logger.plist
The desktop folder is now being monitored. Every time it is changed you should see an output in the system.log (use Console.app).
To deactivate the logger.plist, run:
$ launchctl unload ~/Library/LaunchAgents/logger.plist
The configuration file above uses the WatchPaths option. Alternatively you can also use the
QueueDirectories option. See the launchd man page for more information.
Facebook's watchman, available via Homebrew, also looks nice. It supports also filtering:
These two lines establish a watch on a source directory and then set
up a trigger named "buildme" that will run a tool named "minify-css"
whenever a CSS file is changed. The tool will be passed a list of the
changed filenames.
$ watchman watch ~/src
$ watchman -- trigger ~/src buildme '*.css' -- minify-css
Notice that the path must be absolute.
You might want to take a look at (and maybe expand) my little tool kqwait. Currently it just sits around and waits for a write event on a single file, but the kqueue architecture allows for hierarchical event stacking...
watchdog is a cross-platform python API for watching files / directories, and it has builtin "tricks" tool that allows you to trigger actions (including shell commands) when events occur (including new added file, removed file and changed file).
This is just to mention entr as an alternative on OSX to run arbitrary commands when files change. I find it simple and useful.
brew install entr on macos
apt install entr on Debian/Ubuntu
Here's a one-liner using sschober's tool.
$ while true; do kqwait ./file-to-watch.js; script-to-execute.sh; done
Apple OSX Folder Actions allow you to automate tasks based on actions taken on a folder.
Edit: fsw has been merged into fswatch. In this answer, any reference to fsw should now read fswatch.
I wrote an fswatch replacement in C++ called fsw which features several improvements:
It's a GNU Build System project which builds on any supported platform (OS X v. >= 10.6) with
./configure && make && sudo make install
Multiple paths can be passed as different arguments:
fsw file-0 ... file-n
It dumps a detailed record with all the event information such as:
Sat Feb 15 00:53:45 2014 - /path/to/file:inodeMetaMod modified isFile
Its output is easy to parse so that fsw output can be piped to another process.
Latency can be customised with -l, --latency.
Numeric event flags can be written instead of textual ones with -n, --numeric.
The time format can be customised using strftime format strings with -t, --time-format.
The time can be the local time of the machine (by default) or UTC time with -u, --utc-time.
Getting fsw:
fsw is hosted on GitHub and can be obtained cloning its repository:
git clone https://github.com/emcrisostomo/fsw
Installing fsw:
fsw can be installed using the following commands:
./configure && make && sudo make install
Further information:
I also wrote an introductory blog post where you can find a couple of examples about how fsw works.
My fork of fswatch provides the functionality of inotifywait -m with slightly less (no wait, more! I have a lot more troubles on Linux with inotifywait...) parse-friendly output.
It is an improvement upon the original fswatch because it sends out the actual path of the changed file over STDOUT rather than requiring you to provide a program that it forks.
It's been rock solid as the foundation of a series of scary bash scripts I use to automate stuff.
(this is off-topic) inotifywait on Linux, on the other hand, requires a lot of kludges on top of it and I still haven't figured out a good way to manage it, though I think something based on node.js might be the ticket.
I have a GIST for this and the usage is pretty simple
watchfiles <cmd> <paths...>
To illustrate, the following command will echo Hello World every time that file1 OR file2 change; and the default interval check is 1 second
watchfiles 'echo Hello World' /path/to/file1 /path/to/file2
If I want to check every 5 seconds I can use the -t flag
watchfiles -t 'echo Hello World' /path/to/file1 /path/to/file2
-v enables the verbose mode which shows debug information
-q makes watchfiles execute quietly (# will be shown so the user can see the program is executing)
-qq makes watchfiles execute completely quietly
-h shows the help and usage
https://gist.github.com/thiagoh/5d8f53bfb64985b94e5bc8b3844dba55
I ended up doing this for macOS. I'm sure this is terrible in many ways:
#!/bin/sh
# watchAndRun
if [ $# -ne 2 ]; then
echo "Use like this:"
echo " $0 filename-to-watch command-to-run"
exit 1
fi
if which fswatch >/dev/null; then
echo "Watching $1 and will run $2"
while true; do fswatch --one-event $1 >/dev/null && $2; done
else
echo "You might need to run: brew install fswatch"
fi
If you want to use NodeJS, you can use a package called chokidar (or chokidar-cli actually) for the watching and then use rsync (included with Mac):
Rsync command:
$ rsync -avz --exclude 'some-file' --exclude 'some-dir' './' '/my/destination'
Chokidar cli (installed globally via npm):
chokidar \"**/*\" -c \"your-rsync-command-above\"
sudo fs_usage -f filesys | grep "interesting thing" ?
I can wholeheartedly recommend using watchexec. Built in Rust and It Just Works™ no matter which platform you're on! Straightforward CLI options as well.
Here's a simple single line alternative for users who don't have the watch command who want to execute a command every 3 seconds:
while :; do your-command; sleep 3; done
It's an infinite loop that is basically the same as doing the following:
watch -n3 your-command
I have a bash script like:
#!/bin/bash
echo Hello world!
How do I execute this in Terminal?
Yet another way to execute it (this time without setting execute permissions):
bash /path/to/scriptname
$prompt: /path/to/script and hit enter. Note you need to make sure the script has execute permissions.
cd to the directory that contains the script, or put it in a bin folder that is in your $PATH
then type
./scriptname.sh
if in the same directory or
scriptname.sh
if it's in the bin folder.
You could do:
sh scriptname.sh
This is an old thread, but I happened across it and I'm surprised nobody has put up a complete answer yet. So here goes...
The Executing a Command Line Script Tutorial!
Q: How do I execute this in Terminal?
The answer is below, but first ... if you are asking this question, here are a few other tidbits to help you on your way:
Confusions and Conflicts:
The Path
Understanding The Path (added by tripleee for completeness) is important. The "path" sounds like a Zen-like hacker koan or something, but it is simply a list of directories (folders) that are searched automatically when an unknown command is typed in at the command prompt. Some commands, like ls may be built-in's, but most commands are actually separate small programs. (This is where the "Zen of Unix" comes in ... "(i) Make each program do one thing well.")
Extensions
Unlike the old DOS command prompts that a lot of people remember, you do not need an 'extension' (like .sh or .py or anything else), but it helps to keep track of things. It is really only there for humans to use as a reference and most command lines and programs will not care in the least. It won't hurt. If the script name contains an extension, however, you must use it. It is part of the filename.
Changing directories
You do not need to be in any certain directory at all for any reason. But if the directory is not on the path (type echo $PATH to see), then you must include it. If you want to run a script from the current directory, use ./ before it. This ./ thing means 'here in the current directory.'
Typing the program name
You do not need to type out the name of the program that runs the file (BASH or Python or whatever) unless you want to. It won't hurt, but there are a few times when you may get slightly different results.
SUDO
You do not need sudo to do any of this. This command is reserved for running commands as another user or a 'root' (administrator) user. Running scripts with sudo allows much greater danger of screwing things up. So if you don't know the exact reason for using sudo, don't use it. Great post here.
Script location ...
A good place to put your scripts is in your ~/bin folder.
You can get there by typing
# A good place to put your scripts is in your ~/bin folder.
> cd ~/bin # or cd $HOME/bin
> ls -l
You will see a listing with owners and permissions. You will notice that you 'own' all of the files in this directory. You have full control over this directory and nobody else can easily modify it.
If it does not exist, you can create one:
> mkdir -p ~/bin && cd ~/bin
> pwd
/Users/Userxxxx/bin
A: To "execute this script" from the terminal on a Unix/Linux type system, you have to do three things:
1. Tell the system the location of the script. (pick one)
# type the name of the script with the full path
> /path/to/script.sh
# execute the script from the directory it is in
> ./script.sh
# place the script in a directory that is on the PATH
> script.sh
# ... to see the list of directories in the path, use:
> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ... or for a list that is easier to read:
> echo -e ${PATH//:/\\n}
# or
> printf "%b" "${PATH//:/\\n}"
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
2. Tell the system that the script has permission to execute. (pick one)
# set the 'execute' permissions on the script
> chmod +x /path/to/script.sh
# using specific permissions instead
# FYI, this makes these scripts inaccessible by ANYONE but an administrator
> chmod 700 /path/to/script.sh
# set all files in your script directory to execute permissions
> chmod +x ~/bin/*
There is a great discussion of permissions with a cool chart here.
3. Tell the system the type of script. (pick one)
Type the name of the program before the script. (Note: when using this method, the execute(chmod thing above) is not required
> bash /path/to/script.sh
...
> php /path/to/script.php
...
> python3 /path/to/script.py
...
Use a shebang, which I see you have (#!/bin/bash) in your example. If you have that as the first line of your script, the system will use that program to execute the script. No need for typing programs or using extensions.
Use a "portable" shebang. You can also have the system choose the version of the program that is first in the PATH by using #!/usr/bin/env followed by the program name (e.g. #!/usr/bin/env bash or #!/usr/bin/env python3). There are pros and cons as thoroughly discussed here.
Note: This "portable" shebang may not be as portable as it seems. As with anything over 50 years old and steeped in numerous options that never work out quite the way you expect them ... there is a heated debate. The most recent one I saw that is actually quite different from most ideas is the "portable" perl-bang:
#!/bin/sh
exec perl -x "$0" "$#"
#!perl
Firstly you have to make it executable using: chmod +x name_of_your_file_script.
After you made it executable, you can run it using ./same_name_of_your_file_script
Change your directory to where script is located by using cd command
Then type
bash program-name.sh
And yet one more way
. /path/to/script
What is the meaning of the dot?
If you are in a directory or folder where the script file is available then simply change the file permission in executable mode by doing
chmod +x your_filename.sh
After that you will run the script by using the following command.
$ sudo ./your_filename.sh
Above the "." represent the current directory.
Note!
If you are not in the directory where the bash script file is present then you change the directory where the file is located by using
cd Directory_name/write the complete path
command. Otherwise your script can not run.
I want to watch a folder on my Mac and then execute a bash script, passing it the name of whatever file/folder was just moved into or created in the watched directory.
fswatch
fswatch is a small program using the Mac OS X FSEvents API to monitor a directory.
When an event about any change to that directory is received, the specified
shell command is executed by /bin/bash
If you're on GNU/Linux,
inotifywatch (part of the
inotify-tools package on most distributions) provides similar
functionality.
Update: fswatch can now be used across many platforms including BSD, Debian, and Windows.
Syntax / A Simple Example
The new way that can watch multiple paths - for versions 1.x and higher:
fswatch -o ~/path/to/watch | xargs -n1 -I{} ~/script/to/run/when/files/change.sh
Note: The number output by -o will get added to the end of the xargs command if not for the -I{}. If you do choose to use that number, place {} anywhere in your command.
The older way for versions 0.x:
fswatch ~/path/to/watch ~/script/to/run/when/files/change.sh
Installation with Homebrew
As of 9/12/13 it was added back in to homebrew - yay! So, update your formula list (brew update) and then all you need to do is:
brew install fswatch
Installation without Homebrew
Type these commands in Terminal.app
cd /tmp
git clone https://github.com/alandipert/fswatch
cd fswatch/
make
cp fswatch /usr/local/bin/fswatch
If you don't have a c compiler on your system you may need to install Xcode or Xcode command line tools - both free. However, if that is the case, you should probably just check out homebrew.
Additional Options for fswatch version 1.x
Usage:
fswatch [OPTION] ... path ...
Options:
-0, --print0 Use the ASCII NUL character (0) as line separator.
-1, --one-event Exit fsw after the first set of events is received.
-e, --exclude=REGEX Exclude paths matching REGEX.
-E, --extended Use exended regular expressions.
-f, --format-time Print the event time using the specified format.
-h, --help Show this message.
-i, --insensitive Use case insensitive regular expressions.
-k, --kqueue Use the kqueue monitor.
-l, --latency=DOUBLE Set the latency.
-L, --follow-links Follow symbolic links.
-n, --numeric Print a numeric event mask.
-o, --one-per-batch Print a single message with the number of change events.
in the current batch.
-p, --poll Use the poll monitor.
-r, --recursive Recurse subdirectories.
-t, --timestamp Print the event timestamp.
-u, --utc-time Print the event time as UTC time.
-v, --verbose Print verbose output.
-x, --event-flags Print the event flags.
See the man page for more information.
You can use launchd for that purpose. Launchd can be configured to automatically launch a program when a file path is modified.
For example the following launchd config plist will launch the program /usr/bin/logger when the desktop folder of my user account is modified:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>logger</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/logger</string>
<string>path modified</string>
</array>
<key>WatchPaths</key>
<array>
<string>/Users/sakra/Desktop/</string>
</array>
</dict>
</plist>
To activate the config plist save it to the LaunchAgents folder in your Library folder as "logger.plist".
From the shell you can then use the command launchctl to activate the logger.plist by running:
$ launchctl load ~/Library/LaunchAgents/logger.plist
The desktop folder is now being monitored. Every time it is changed you should see an output in the system.log (use Console.app).
To deactivate the logger.plist, run:
$ launchctl unload ~/Library/LaunchAgents/logger.plist
The configuration file above uses the WatchPaths option. Alternatively you can also use the
QueueDirectories option. See the launchd man page for more information.
Facebook's watchman, available via Homebrew, also looks nice. It supports also filtering:
These two lines establish a watch on a source directory and then set
up a trigger named "buildme" that will run a tool named "minify-css"
whenever a CSS file is changed. The tool will be passed a list of the
changed filenames.
$ watchman watch ~/src
$ watchman -- trigger ~/src buildme '*.css' -- minify-css
Notice that the path must be absolute.
You might want to take a look at (and maybe expand) my little tool kqwait. Currently it just sits around and waits for a write event on a single file, but the kqueue architecture allows for hierarchical event stacking...
watchdog is a cross-platform python API for watching files / directories, and it has builtin "tricks" tool that allows you to trigger actions (including shell commands) when events occur (including new added file, removed file and changed file).
This is just to mention entr as an alternative on OSX to run arbitrary commands when files change. I find it simple and useful.
brew install entr on macos
apt install entr on Debian/Ubuntu
Here's a one-liner using sschober's tool.
$ while true; do kqwait ./file-to-watch.js; script-to-execute.sh; done
Apple OSX Folder Actions allow you to automate tasks based on actions taken on a folder.
Edit: fsw has been merged into fswatch. In this answer, any reference to fsw should now read fswatch.
I wrote an fswatch replacement in C++ called fsw which features several improvements:
It's a GNU Build System project which builds on any supported platform (OS X v. >= 10.6) with
./configure && make && sudo make install
Multiple paths can be passed as different arguments:
fsw file-0 ... file-n
It dumps a detailed record with all the event information such as:
Sat Feb 15 00:53:45 2014 - /path/to/file:inodeMetaMod modified isFile
Its output is easy to parse so that fsw output can be piped to another process.
Latency can be customised with -l, --latency.
Numeric event flags can be written instead of textual ones with -n, --numeric.
The time format can be customised using strftime format strings with -t, --time-format.
The time can be the local time of the machine (by default) or UTC time with -u, --utc-time.
Getting fsw:
fsw is hosted on GitHub and can be obtained cloning its repository:
git clone https://github.com/emcrisostomo/fsw
Installing fsw:
fsw can be installed using the following commands:
./configure && make && sudo make install
Further information:
I also wrote an introductory blog post where you can find a couple of examples about how fsw works.
My fork of fswatch provides the functionality of inotifywait -m with slightly less (no wait, more! I have a lot more troubles on Linux with inotifywait...) parse-friendly output.
It is an improvement upon the original fswatch because it sends out the actual path of the changed file over STDOUT rather than requiring you to provide a program that it forks.
It's been rock solid as the foundation of a series of scary bash scripts I use to automate stuff.
(this is off-topic) inotifywait on Linux, on the other hand, requires a lot of kludges on top of it and I still haven't figured out a good way to manage it, though I think something based on node.js might be the ticket.
I have a GIST for this and the usage is pretty simple
watchfiles <cmd> <paths...>
To illustrate, the following command will echo Hello World every time that file1 OR file2 change; and the default interval check is 1 second
watchfiles 'echo Hello World' /path/to/file1 /path/to/file2
If I want to check every 5 seconds I can use the -t flag
watchfiles -t 'echo Hello World' /path/to/file1 /path/to/file2
-v enables the verbose mode which shows debug information
-q makes watchfiles execute quietly (# will be shown so the user can see the program is executing)
-qq makes watchfiles execute completely quietly
-h shows the help and usage
https://gist.github.com/thiagoh/5d8f53bfb64985b94e5bc8b3844dba55
I ended up doing this for macOS. I'm sure this is terrible in many ways:
#!/bin/sh
# watchAndRun
if [ $# -ne 2 ]; then
echo "Use like this:"
echo " $0 filename-to-watch command-to-run"
exit 1
fi
if which fswatch >/dev/null; then
echo "Watching $1 and will run $2"
while true; do fswatch --one-event $1 >/dev/null && $2; done
else
echo "You might need to run: brew install fswatch"
fi
If you want to use NodeJS, you can use a package called chokidar (or chokidar-cli actually) for the watching and then use rsync (included with Mac):
Rsync command:
$ rsync -avz --exclude 'some-file' --exclude 'some-dir' './' '/my/destination'
Chokidar cli (installed globally via npm):
chokidar \"**/*\" -c \"your-rsync-command-above\"
sudo fs_usage -f filesys | grep "interesting thing" ?
I can wholeheartedly recommend using watchexec. Built in Rust and It Just Works™ no matter which platform you're on! Straightforward CLI options as well.
Here's a simple single line alternative for users who don't have the watch command who want to execute a command every 3 seconds:
while :; do your-command; sleep 3; done
It's an infinite loop that is basically the same as doing the following:
watch -n3 your-command