File Change Monitoring Tool - Detects file changes and executes commands
※ Most of this document was AI-generated by submitting issues to an agent. Some parts (Concept, Usage Scenarios, Test) were written manually.
| Item | Link |
|---|---|
| 📊 Development Status | generated-docs/development-status |
This is a file monitoring tool that watches for changes in file timestamps and executes commands when a file is updated.
- Monitor multiple files simultaneously
- Execute custom commands on file change
- Configurable via TOML configuration file
- Lightweight and easy to use
- Clone this repository:
git clone https://github.com/cat2151/cat-file-watcher.git
cd cat-file-watcher- Install dependencies:
pip install -r requirements.txtGet started now with minimal setup! It works with just one line in a TOML file:
- Create a configuration file (
config.toml):
files = [{path = "test.txt", command = "echo ファイルが変更されました"}]- Create the file to be monitored:
touch test.txt- Start the file watcher:
python -m src --config-filename config.tomlThat's it! It will monitor test.txt for changes and execute the command if it changes!
Try editing the file:
echo "テスト" >> test.txtYou will see "ファイルが変更されました" (File changed) displayed in the console.
Note: The single-line format above is a formal TOML notation using inline array representation. A more readable multi-line format is also available (see the Configuration section for details).
Run the file watcher by specifying a configuration file:
python -m src --config-filename config.tomlArguments:
--config-filename: Path to the TOML configuration file (required)
Create a TOML configuration file to define the files to monitor and the commands to execute:
# Default monitoring interval
# Time format: "1s" (1 second), "2m" (2 minutes), "3h" (3 hours), "0.5s" (0.5 seconds)
default_interval = "1s"
# Interval for checking changes to the configuration file itself
config_check_interval = "1s"
# File path for command execution logs (optional)
log_file = "command_execution.log"
# File path for error logs (optional)
# error_log_file = "error.log"
# File path for command suppression logs (optional)
# suppression_log_file = "suppression.log"
# Time period definitions (optional)
[time_periods]
business_hours = { start = "09:00", end = "17:00" }
night_shift = { start = "23:00", end = "01:00" }
[files]
"myfile.txt" = { command = "echo 'File changed!'" }
"script.py" = { command = "python -m pytest tests/", interval = "2s" }
"src/main.py" = { command = "make build", suppress_if_process = "vim|emacs|code" }
"batch.csv" = { command = "./process.sh", time_period = "night_shift" }
"important.txt" = { command = "backup.sh", enable_log = true }
"lib/module.c" = { command = "gcc -c module.c -o module.o", cwd = "./lib" }The configuration file requires a [files] section where each entry maps a file name to a command:
- Key: The path to the file or directory to monitor (relative or absolute path)
- For files: Executes the command when the file's modification time changes
- For directories: Executes the command when the directory's modification time changes (e.g., adding/deleting files)
- Value: An object with a
commandfield containing the shell command to executecommand(required): The shell command to execute when the file or directory changes.interval(optional): The monitoring interval for this file or directory. Specify in time format ("1s", "2m", "3h", "0.5s"). Decimal values are also allowed (e.g., "0.5s" for 0.5 seconds). If omitted,default_intervalwill be used.suppress_if_process(optional): A regular expression pattern that matches running process names. If a matching process is found, command execution will be skipped. This is useful for preventing actions from being triggered when certain programs like editors are running.time_period(optional): The name of the time period during which the file or directory should be monitored. Specify a time period name defined in the[time_periods]section. Monitoring will only occur within the specified time period.enable_log(optional): If set totrue, detailed command execution will be logged to a log file (default:false). Thelog_filesetting is required in the global configuration.cwd(optional): Changes the working directory to the specified path before executing the command. This ensures that relative paths within the command are resolved from the specified directory.
default_interval(optional): The default monitoring interval for all files and directories. Specify in time format ("1s", "2m", "3h", "0.5s"). Decimal values are also allowed (e.g., "0.5s" for 0.5 seconds). If omitted, "1s" (1 second) will be used.config_check_interval(optional): The interval for checking changes to the configuration file itself. Specify in time format ("1s", "2m", "3h", "0.5s"). The configuration file will be automatically reloaded if it changes. If omitted, "1s" (1 second) will be used.log_file(optional): The path to the log file for recording detailed command execution. If set, command execution information (timestamp, path, TOML configuration content) for files or directories withenable_log = truewill be recorded in this file.error_log_file(optional): The path to the error log file for recording details of command execution errors. If set, detailed information such as error messages upon command failure, the executed command, standard error output, and stack traces will be recorded in this file.suppression_log_file(optional): The path to the log file for recording details of command execution suppression. If set, information about skipped command executions due tosuppress_if_process(timestamp, file path, process pattern, matched process) will be recorded in this file.
You can define time periods in the [time_periods] section (optional):
- Each time period is defined with a name.
start: Start time (HH:MM format, e.g., "09:00").end: End time (HH:MM format, e.g., "17:00").- Time periods spanning across midnight are also supported (e.g.,
start = "23:00", end = "01:00"). - If you specify a time period name using the
time_periodparameter for each file, that file or directory will only be monitored within that time period.
Example:
[time_periods]
business_hours = { start = "09:00", end = "17:00" } # Regular hours
night_shift = { start = "23:00", end = "01:00" } # Spanning midnightFor a complete example of various use cases, please refer to examples/config.example.toml.
# Set default monitoring interval to 1 second
default_interval = "1s"
# Set config file change check interval to 1 second
config_check_interval = "1s"
# Log file for detailed command execution (optional)
log_file = "command_execution.log"
# Error log file (optional)
# error_log_file = "error.log"
# Command execution suppression log file (optional)
# suppression_log_file = "suppression.log"
# Time period definitions
[time_periods]
business_hours = { start = "09:00", end = "17:00" }
after_hours = { start = "18:00", end = "08:00" } # Spanning midnight
[files]
# Use default interval (check every 1 second)
"document.txt" = { command = "cp document.txt document.txt.bak" }
# Specify custom interval (check every 0.5 seconds)
"app.log" = { command = "notify-send 'Log Updated' 'New entries in app.log'", interval = "0.5s" }
# Specify custom interval (check every 5 seconds)
"config.ini" = { command = "systemctl reload myapp", interval = "5s" }
# Monitor only during business hours
"report.txt" = { command = "python generate_report.py", time_period = "business_hours" }
# Monitor only outside business hours (e.g., for batch processing)
"batch.csv" = { command = "./process_batch.sh", time_period = "after_hours" }
# Enable logging for important files (records timestamp, file path, and config content)
"important.txt" = { command = "backup.sh", enable_log = true }- The tool reads the TOML configuration file.
- It monitors the modification timestamps of all specified files.
- When a file's timestamp changes, it executes the associated command.
- The configuration file itself is also monitored and automatically reloaded if it changes.
- This process continuously repeats until stopped by Ctrl+C.
Important: Commands are executed sequentially.
- When a file change is detected and a command is executed, the next file will not be checked until that command completes (or times out after 30 seconds for foreground execution).
- For example, if a command for one file takes 25 seconds, monitoring of other files will be paused for those 25 seconds.
- Even if other files are updated during this time, they will not be detected until the running command completes (they will be detected in the next main loop after the command finishes).
- The current implementation does not support parallel monitoring and execution of multiple files.
For commands that require long execution times, you need to implement them to run in the background within the command or launch them as separate processes.
Methods for Non-blocking Execution:
- Linux/macOS: Append
&to the end of the command (e.g.,command = "long_task.sh &"). - Windows: Prepend
startto the command (e.g.,command = "start long_task.bat").
The standard output and standard error of the executed command are displayed in the console in real-time:
- Output Display: The standard output and standard error of the command are sequentially displayed in the console during execution. Even for long-running commands, you can monitor their progress in real-time.
- On Failure: If a command fails (exit code other than 0), a message like
Error: Command failed for '<file path>' with exit code <code_number>will be displayed. - Error Log File: If
error_log_fileis configured, the error message and the executed command upon failure will be recorded in the log file.
The timeout for commands executed in the foreground is set to 30 seconds; exceeding this will result in a timeout error. For commands that require longer execution, please use background execution (using &). Commands executed in the background are not subject to the timeout limit, as subprocess.run() completes immediately.
Prioritize simple and maintainable TOML descriptions.
For easily monitoring file updates and operating with ease, use cat-file-watcher.
For quickly enabling/disabling update monitoring of scattered files, use cat-file-watcher.
For utilizing its unique features, use cat-file-watcher.
For more advanced features, use other applications.
For TypeScript application development, etc., a standard task runner.
Setting up the development environment:
# Install dependencies (for runtime environment)
pip install -r requirements.txt
# Install development dependencies (including Ruff)
pip install -r dev-requirements.txtThis project uses Ruff to maintain code quality.
# Linter check
ruff check src/
# Fix auto-fixable issues
ruff check --fix src/
# Check code formatting
ruff format --check src/
# Apply code formatting
ruff format src/# Run all tests
pytest
# Run tests with detailed output
pytest -v-
Linux
- All tests are designed for Linux.
- The test code was generated by GitHub Copilot Coding Agent and developed using TDD on GitHub Actions (Linux Runner).
-
Windows
- Running tests on Windows without WSL2 will result in many test failures (red) because the tests are designed for Linux.
- To run tests in a Windows environment, use WSL2.
- Specifically, install WSL2, then prepare by running
wsl pip install -r dev-requirements.txt, and finally executewsl pytest. - While a few tests might still show red with WSL2, this is acceptable. The criterion is that tests should be green when TDD was performed by submitting issues to the agent.
MIT License - See the LICENSE file for details.
※ The English version of README.md is automatically generated by GitHub Actions using Gemini's translation based on README.ja.md.
Big Brother watched your files. Now the cat does. 🐱