Linux run command on file change

How to run a command when a directory’s contents are updated?

There is a directory A whose contents are changed frequently by other people. I have made a personal directory B where I keep all the files that have ever been in A . Currently, I just occasionally run rsync to get the files to be backed up from A to B . However, I fear the possibility that some files will get added in A , and then removed from A before I get the chance to copy them over to B . What is the best way to prevent this from occurring? Ideally, I’d like to have my current backup script run every time the contents of A get changed.

4 Answers 4

If you have inotify-tools installed you can use inotifywait to trigger an action if a file or directory is written to:

#!/bin/sh dir1=/path/to/A/ while inotifywait -qqre "attrib,modify,close_write,move,move_self,create,delete,delete_self" "$dir1"; do /run/backup/to/B done

Where the -qq switch is completely silent, -r is recursive (if needed) and -e is the event to monitor. From man inotifywait :

attrib The metadata of a watched file or a file within a watched directory was modified. This includes timestamps, file permissions, extended attributes etc.

modify A watched file or a file within a watched directory was written to.

close_write A watched file or a file within a watched directory was closed, after being opened in writeable mode. This does not necessarily imply the file was written to.

move A file or directory was moved from or to a watched directory. Note that this is actually implemented simply by listening for both moved_to and moved_from, hence all close events received will be output as one or both of these, not MOVE.

move_self A watched file or directory was moved. After this event, the file or directory is no longer being watched.

create A file or directory was created within a watched directory.

delete A file or directory within a watched directory was deleted.

delete_self A watched file or directory was deleted. After this event the file or directory is no longer being watched. Note that this event can occur even if it is not explicitly being listened for.

Источник

How to Execute Command When File Changes in Linux?

Invicti Web Application Security Scanner – the only solution that delivers automatic verification of vulnerabilities with Proof-Based Scanning™.

You’ve come to the right place if you want to learn how to run Linux commands when any file in a working directory change and when new files are created.

In Linux, you may use cron to schedule commands to run at certain times.

But what if you need commands to be run every time a file is modified, or a new file is added to a directory?

That’s also easily achievable, and there are some command-line tools to perform that.

watchexec

watchexec is a handy and standalone tool that monitors a given working directory and executes a command if it detects any changes like file updation or new file creation.

Читайте также:  Linux контроллер домена windows

Features

  • It does not require a complex command line involving xargs (extended arguments).
  • Checks for changes in the current directory and all subdirectories in real-time.
  • There is no need for a language runtime, and it is not connected to any specific language or ecosystem.
  • .gitignore and .ignore are used by default to decide which files to ignore notifications for.
  • Process groups are used to keep track of forking programs.
  • Watching files with a certain extension is supported.
  • It’s compatible with OS X, Linux, and Windows.
  • Filtering and ignoring events based on glob (File-search patterns for finding partially identical filenames is possible.

Installation of watchexec

To easily install watchexec tool, paste the following link into the terminal or a shell prompt, and press enter.

Linux & macOS

curl -sS https://webinstall.dev/watchexec | bash

After the successful installation, the path will be displayed on the screen. In my case, this tool was installed in /root/.local/bin

┌──(root💀kali)-[~] └─# curl -sS https://webinstall.dev/watchexec | bash Thanks for using webi to install 'watchexec@stable' on 'Linux/x86_64'. Have a problem? Experience a bug? Please let us know: https://github.com/webinstall/webi-installers/issues Lovin' it? Say thanks with a Star on GitHub: https://github.com/webinstall/webi-installers Found /root/Downloads/webi/watchexec/cli-v1.18.9/watchexec-1.18.9-x86_64-unknown-linux-musl.tar.xz Extracting /root/Downloads/webi/watchexec/cli-v1.18.9/watchexec-1.18.9-x86_64-unknown-linux-musl.tar.xz Installing to /root/.local/opt/watchexec-vcli-v1.18.9/bin/watchexec Installed 'watchexec vcli-v1.18.9' as /root/.local/bin/watchexec 

And after installation, navigate to the .local/bin repository and check whether the file is there or not by using these commands.

The next step is to export the path to use the watchexec tool.

export PATH="/root/.local/bin:$PATH"

To run, Just type watchexec in the terminal as a root user. Use this command to see which flags and options can be used with watchexec tool.

Sample Example Commands

  • Call ls -la when any file changes in this directory/subdirectory. This command shows all the files present in the directory whenever it detects any modification.
  • Whenever any of the python, js, CSS, or Html extension files in the current directory change, run the command. Here you can pass any command you want. The file extensions should be separated by a comma.
 watchexec --exts py,js,css,html
  • Run command when any file in lib or src changes. “-w” option watches a specific file or directory in the system.
watchexec -e html -r tor watchexec -e js,py -r mysql

Here, “-r” option restarts the process or service if it’s running in the system.

For more watchexec usage examples, you can visit the official GitHub repository.

entr

entr is a simple and excellent command-line utility for running arbitrary commands when any modifications occur in a given directory.

entr” stands for Event Notify Test Runner. This tool was created with the goal of making rapid feedback and automated testing.

Installation

entr is pre-installed in the Linux distribution. In case it’s missing, you need to install it manually.

This tool is simple to use and can be installed with the following command.

Or you can also install it by cloning the official Git repository.

git clone https://github.com/eradman/entr.git

Next, navigate to that directory and install the requirements using the below commands.

./configure make test make install

To see available build options run ./configure -h

Sample Example Commands

To see the options and arguments available for entr command. Use the following command.

Читайте также:  Current linux operating systems

This command displays the user manual for the entr command.

NAME entr — run arbitrary commands when files change SYNOPSIS entr [-acdnprsz] utility [argument /_ . ] DESCRIPTION A list of files provided on standard input, and the utility is executed using the supplied arguments if any of them change. entr waits for the child process to finish before responding to subsequent file system events. A TTY is also opened before entering the watch loop in order to support interac‐ tive utilities. The arguments are as follows: -a Respond to all events which occur while the utility is running. Without this option, entr consolidates events in order to avoid looping. This option has no effect in conjunction with the -r flag. -c Clear the screen before invoking the utility specified on the command line. Specify twice to erase the scroll back buffer. -d Track the directories of regular files provided as input and exit if a new file is added. This option also enables directories to be specified explicitly. If specified twice, all new entries to a directory are recognized, otherwise files with names beginning with ‘.’ are ig‐ nored. -n Run in non-interactive mode. In this mode entr does not attempt to read from the TTY or change its properties. -p Postpone the first execution of the utility until a file is modified. Manual page entr(1) line 1 (press h for help or q to quit) 
  • To launch and auto-reload a MySQL server when any JavaScript file changes in the working directory. Each time the changes are saved to the file, entr reloads the MySQL server.

For more details and examples on entr command, you can visit their official GitHub repository.

Final Words 👩‍💻

I hope you found this article very useful in learning how to run Linux commands when any file in a given directory changes and when new files are created.

You may also be interested in learning how to remove files and directories in Linux.

Источник

Command to monitor file changes within a directory and execute command

to compile it into HTML format. I am trying to automate the process. so far I have come with this using entr:

ls *.adoc | entr asciidoctor -q *.adoc 

but only works with existing folder not for subfolders. I have tried this variation, but it doesn’t work:

find . -name '*.adoc' | entr asciidoctor -q *.adoc 

4 Answers 4

Linux provides a nice interface for monitoring all file system events like creating, modifying, removing files. The interface is inotify family of system calls, the userspace utilities leveraging these calls are provided by the inotify-tools package in Ubuntu (available on the universe repository). If you don’t have it already, install by:

sudo apt-get install inotify-tools 

inotify-tools provides inotifywait and inotifywatch binaries, we need the first one.

So you want to run the command asciidoctor -q some_file when any .adoc file is modified ( some_file will replaced by that), if so assuming your .adoc files are in directory /foo/bar , you can set the watch:

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc 
  • -q enables the quiet mode, no info from inotifywait itself
  • -m enables monitor mode, otherwise it will exit after the first event
  • —event modify , we are only interested in modify event i.e. when a file is modified. Other possible values include open , close etc.
  • —format %w , we only want the file name that is modified rather than bunch of other info as we will use the file name as input to another command
  • /foo/bar/*.adoc will be expanded to all .adoc files under /foo/bar directory
Читайте также:  Linux proxy all ports

Now the above will show you the filename whenever any is modified, now to run the command on the filename (assuming the command takes arguments via STDIN):

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc | while read -r file ; do asciidoctor -q "$file" done 

You can also setup a recursive watch on the directory, you will then need to use grep to filter the desired files only. Here setting the watch recursively ( -r ) on directory /foo/bar and using grep to filter only .adoc files:

inotifywait -qrm --event modify --format '%w%f' /foo/bar | grep '\.adoc$' | while read -r file ; do asciidoctor -q "$file" done 

When watching directories the output format specifier %w resolves to the directory name, so we need %f to get the file name. While watching files, %f would resolve to empty string.

Note that, you can also run inotifywait in daemon ( -d ) mode, you can also script the whole thing, and/or run in background, and/or play with it more other options.

Also, you can replace asciidoctor with any other command of your choice, if you want.

Check man inotifywait to get more idea.

Источник

How to run a shell script when a file or directory changes?

@MerlynMorgan-Graham I’d move this to superuser, because the answer might not have anything do with programming — i.e. there might be some program or configuration option that can be used, without any programming needed. I had the same question, and searched superuser first :p

12 Answers 12

You may try entr tool to run arbitrary commands when files change. Example for files:

$ ls -d * | entr sh -c 'make && make test' 
$ ls *.css *.html | entr reload-browser Firefox 

or print Changed! when file file.txt is saved:

$ echo file.txt | entr echo Changed! 

For directories use -d , but you’ve to use it in the loop, e.g.:

while true; do find path/ | entr -d echo Changed; done 
while true; do ls path/* | entr -pd echo Changed; done 

entr is the simplest, most composable and unix-y tool for the job. Love it. incron can be replaced with entr and a process manager like runit , s6 or even systemd .

I have a script regularly appending to a log file. When I use entr to monitor that log file and touch the log, everything works fine, but when the script appends to the file, entr fails. This may be because I have noatime set in my fstab for my ssd — but that only stops the updating of the access time not the modify time, so this confuses me. I have then tried entr -cdr on the directory of files that are updated with the log. That recognizes with the directory contents change, but the -r does not work. The entr process just ends.

Источник

Оцените статью
Adblock
detector