#How to Run a Linux Command When a File Set Changes – CloudSavvy IT

Table of Contents
“#How to Run a Linux Command When a File Set Changes – CloudSavvy IT”
Learn how to run Linux commands when any file in a watched set of files changes, and when new files are created. We show you how to use this flexible tool.
The entr Command
You can set commands to run at specific times in Linux, using cron
. It’s easy, reliable, and flexible. But what if you need to have commands executed whenever a file changes, or if a new file is added to a directory? That’s possible, too, and there’s more than one way to do it. The entr
command is a refreshingly straightforward way to achieve that functionality.
Some systems, such as the Hugo static site generator, have a feature that automatically rebuilds your website if a file changes, or if a new file is added to the site. That little feature makes a significant difference to your workflow. With Hugo, you’re able to have your development version of the website in your browser as you edit the files that make up your site. Each time you save your changes or create a file, the website is rebuilt in milliseconds, and the changes are pushed to your browser. Instant feedback is fantastic.
The entr
command brings that type of capability to any set of files. The command that is launched when a change is detected is arbitrary. It can be a standard Linux command, an alias, a shell function, or a script.
Installing entr
To install entr
on Ubuntu, use this command:
sudo apt-get install entr
To install entr
on Fedora, type:
sudo dnf install entr
On Manjaro, the command is:
sudo pacman -Syu entr
A Simple Example
We’ll use the touch command to create a text file called “example.txt” and tell entr
to monitor that file.
The entr
command accepts the filenames it should monitor via STDIN
and accepts the command it should run as command line parameters.
The easiest way to pass a filename to entr
is to use ls
to list it, and pipe that into entr
. When the file changes, entr
will launch wc
command to count the lines, words, and characters in the file.
The /_
parameter is a placeholder for the filename of the file that was passed to entr
. If a group of files is passed to entr
, such as *.txt
, the /_
parameter would be replaced by the last file to be changed.
touch example.txt
ls example.txt | entr wc /_
Each time the changes are saved to the file, entr
launches wc
. To stop entr
, hit q
, or Ctrl+c
.
RELATED: What Are stdin, stdout, and stderr on Linux?
Practical Uses
Now that we’ve seen entr
in action and you understand the principle, let’s look at some more useful scenarios.
We’ll make entr
monitor the files in the current directory. If any of the files are modified, we want entr
to launch make
for us to rebuild our project. We’ll chain another command, make test
, to run some tests on the new build. The AND operator &&
will only launch the second command if the first completes without any issues.
The -s
(shell) option makes sure that the interpreter used is the one defined in the SHELL environment variable. This ensures entr
receives the exit code from the first make
command.
ls | entr -s 'make && make test'
Using the ls
command to send the list of all filenames in the directory to entr
is a bit clunky. You might have files in the directory that are part of the project but are not actually build files. Perhaps they are design notes or a to-do list. You don’t need to have your project rebuilt every time you change one of those non-code files.
We can refine the command so that it monitors only the appropriate source code files. This command monitors the C source code and header files.
ls *.[ch] | entr -s 'make && make test'
Of course, we’re not limited to launching make
. You might have a custom build script that you’d prefer to use.
ls *.[ch] | entr script.sh
Leveraging Git
The entr
command isn’t Git-ware, but we can still use some of Git’s capabilities to smooth our workflow.
The git ls-file
command will list the files that are in Git’s index and working source tree, taking into account the exceptions that have been defined in your “.gitignore” file. That’s a ready-made list of the files that we’re interested in, so let’s use that as the source of the files to monitor.
git ls-files | entr script.sh
The ls-files
command accepts command-line options. These can be used to further filter or augment the files list returned by Git:
- -c: Show cached files.
- -d: Show deleted files.
- -m: Show modified files.
- -o: Show untracked files.
The --exclude-standard
option is a shorthand way to tell Git to ignore files that match the entries in the “.git/info/exclude”, local “.gitignore”, and global “.gitignore” files.
git ls-files -cdmo --exclude-standard | entr 'make && make test'
That’ll catch a lot of eventualities, but it won’t cope with a new file being created. And the new file won’t be in Git. We can still cope with that situation, using a little bit of Bash scripting and a feature of entr
.
The -d
(directory) option causes entr
to monitor the files in a directory and to exit if a new file is added. By wrapping our entr
command in a while/do
loop, the entire entr
command line will be automatically restarted, and the new file will be picked up and acted upon. Files and directories whose names start with a period “.
” are ignored.
while true; do { git ls-files; git ls-files . --exclude-standard --others; } | entr -d ./script.sh done
Restarting Servers and Interpreters
Perhaps you work with an interpreted language like Ruby. Each time your program file is changed, you need to stop and restart the Ruby interpreter. You can handle these types of use cases with the -r
(restart) option.
To monitor a program file called “hello_world.rb”, and to stop and restart the Ruby interpreter each time the program file changes, use this command:
ls hello_world.rb | entr -r ruby hello_world.rb
Each time the program file is edited and saved, the Ruby interpreter is restarted and the program reloaded.
The program initially contained:
puts "Hello, World!"
It was edited to say:
puts "Hello, CloudSavvyIT!"
When this was saved, entr
restarted the Ruby interpreter, and reloaded the program.
The file was edited once more to add the word “readers” and saved to the hard drive.
puts "Hello, CloudSavvyIT readers!"
You can see the three outputs in the screenshot. If you press the spacebar
, entr
will restart the command whether you’ve changed the program file or not.
Not Just for Programmers
Because the command launched by entr
can be anything, including shell scripts, the scope for using entr
to automate processes is virtually limitless.
Perhaps you have a directory that has files dropped into it by secure FTP, or rsync, or curl. You could have these files automatically copied somewhere else, or compressed, or searched by grep for the word “error”.
This makes it a great tool for system administrators and developers alike.
If you liked the article, do not forget to share it with your friends. Follow us on Google News too, click on the star and choose us from your favorites.
For forums sites go to Forum.BuradaBiliyorum.Com
If you want to read more like this article, you can visit our Technology category.