Added command execution support
This commit is contained in:
66
README.md
66
README.md
@@ -2,8 +2,11 @@
|
||||
|
||||
**Wolf** is a configurable file watchdog for Linux platform written in C. **Wolf** monitors
|
||||
a set of files or directories and prints out a log event each time the watched resources changes. The watchdog
|
||||
can be configured to watch for any kind of event, that includes file creation and deletion, file moving, I/O and
|
||||
permission changing. **Wolf** relies on the `inotify(7)` system call, therefore it is only compatible with Linux-based systems.
|
||||
can be configured to monitor any kind of event, that includes file creation and deletion, file moving, I/O and
|
||||
permission changes. Additionally, **Wolf** can execute an user-defined command every time a watchdog detects a
|
||||
change, thus allowing you to easily build complex pipelines without the need to employ any additional tool.
|
||||
|
||||
**Wolf** relies on the `inotify(7)` system call, therefore it is only compatible with Linux-based systems.
|
||||
|
||||
## Building
|
||||
The single source file(`wolf.c`) of the watchdog can be compiled using any C99 compiler. To build it, issue the following command:
|
||||
@@ -98,16 +101,57 @@ R '/home/marco/wolf' (dir)
|
||||
P '/home/marco/wolf/a.out' (file)
|
||||
W '/home/marco/wolf/a.out' (file)
|
||||
```
|
||||
Additionally, if you want to execute a custom command every time a watchdog detects a change, you can do so by
|
||||
using the `-e,--exec` option. For instance, suppose that you have a Python file(`foo.py`) with the following content:
|
||||
|
||||
## Caveats
|
||||
**Wolf** relies on the Linux `inotify(7)` system call to implement the file tracking mechanism. Before using this
|
||||
tool you should be aware of the following idiosyncrasies related to the way this system interface works:
|
||||
```py
|
||||
def square(x):
|
||||
return x ** 2
|
||||
|
||||
1. `inotify` is **NOT** recursive. Meaning that you cannot monitor subdirectories of a watched directory;
|
||||
2. `inotify` can only work within files for which you already have reading and writing permissions;
|
||||
3. `inotify` removes deleted files from the `inotify_add_watch(2)`, meaning that a watchdog is automatically
|
||||
removed from a deleted file. To add it again, the program have to be restarted;
|
||||
4. `inotify` is quite verbose by design. For instance if you try to write to a **non-empty** watched file
|
||||
print(f"10^2 = {square(10)}")
|
||||
```
|
||||
|
||||
and you want to continously evaluate it as soon as you save it to the disk. To do this, you can use **Wolf** as described
|
||||
below:
|
||||
|
||||
```sh
|
||||
$> ./wolf -w --exec 'python foo.py'
|
||||
```
|
||||
|
||||
Each time a write event is detected by the watchdog, the supplied command will be issued, causing the program
|
||||
to be automatically evaluated, that is:
|
||||
|
||||
```sh
|
||||
$> ./wolf -w --exec 'python foo.py'
|
||||
[2024-08-20 16:24:43] W 'foo.py' (file)
|
||||
10^2 = 100
|
||||
[2024-08-20 16:24:55] W 'foo.py' (file)
|
||||
10^2 = 100
|
||||
5^2 = 25
|
||||
[2024-08-20 16:25:10] W 'foo.py' (file)
|
||||
10^2 = 100
|
||||
5^2 = 25
|
||||
4^2 = 16
|
||||
```
|
||||
|
||||
Be sure to read the _caveats_ section to learn more about the concurrent aspects of this feature and how **Wolf**
|
||||
spawns a new process.
|
||||
|
||||
## Technical details
|
||||
Below there is a brief list of the things you should be aware of when using **Wolf**.
|
||||
|
||||
- `inotify` is **NOT** recursive. Meaning that you cannot monitor subdirectories of a watched directory;
|
||||
- `inotify` can only work within files for which you already have reading and writing permissions;
|
||||
- The `-e,--exec` option works by spawning a child process using the `fork(2)` system call; thus, the command is being executed
|
||||
in a new process;
|
||||
- The `-e,--exec` option is a **NON-BLOCKING** feature, meaning that the parent process will continue to log new changes while the
|
||||
child process execute the supplied command; therefore the parent process will **NOT** wait for the child(s) process to terminate;
|
||||
- Since the parent process does not await for the child process to complete it will also not handle its return code, thus the exit
|
||||
status of any supplied command is ignored.
|
||||
- Any `SIGCHLD` signal generated by a child process is ignored, therefore the process reaping of any child is delegated to the kernel;
|
||||
- `inotify` removes deleted files from the `inotify_add_watch(2)`, meaning that, after a file is being deleted, the watchdog associated with it
|
||||
is automatically removed as well. To add it again, the program has to be restarted;
|
||||
- `inotify` is quite verbose by design. For instance if you try to write to a **non-empty** watched file
|
||||
using the `echo(1)` command along with a _redirection_(i.e., `echo 'hello world' > foo`), the watchdog will
|
||||
log two events:
|
||||
|
||||
@@ -136,7 +180,7 @@ exit_group(0) = ?
|
||||
+++ exited with 0 +++
|
||||
```
|
||||
|
||||
Since `inotify(1)` intercepts both, **wolf** will also log twice the same operation.
|
||||
Since `inotify(1)` intercepts both, **wolf** will also log the same operation twice.
|
||||
|
||||
## License
|
||||
[GPLv3](https://choosealicense.com/licenses/gpl-3.0/)
|
||||
|
||||
Reference in New Issue
Block a user