Running Multiple Rust Binaries When They Change With fswatch
January, 2023TL;DR
I use this command to watch for new rust binary source files and run them whenever they are created or changed.
fswatch --event Updated -e ".*" -i "\.rs$" -0 . \
| xargs -0 -I{} basename {} ".rs" \
| xargs -I{} sh -c \
'export RUNFILE="{}" && clear && cargo run --bin $RUNFILE'
(It also clears the console before running the file which helps me track what's happening.)
THE DETAILS
I'm making a bunch of Rust binaries with examples
that are just a few lines long. There's going
to be a few hundred of them. I don't want to do
Cargo new
for each one to avoid eating up a lot
of space. Instead, I'm placing them all in a
single project.
Running each one is a straight forward matter
of calling cargo run
with the --bin
flag
and the name. For example:
cargo run --bin source_name
The trick is that I want to run them automatically
when I create or change a file. There's a cargo-watch
tool for this kind of thing, but I haven't been able to
figure out how to make it do what I want with
multiple binaries.
The solution I came up with is to use fswatch
and
xargs
to handle the functionality.
The first version of the code looked like this:
fswatch --event Updated -e ".*" -i "\.rs$" -0 . \
| xargs -0 -I{} basename {} ".rs" \
| xargs -I{} cargo run --bin {}
Running that inside the src/bin
directory fires
off the run
process whenever a new file is
added or an existing one is changed.
(TODO: Write up all the details of all the parts of the code)
The cargo output can get verbose which can make it hard to distinguish one run from another. Adding a clear call took care of that with some extra gymnastics. The final version of the code looks like this (which is the same as the start of the article)
fswatch --event Updated -e ".*" -i "\.rs$" -0 . \
| xargs -0 -I{} basename {} ".rs" \
| xargs -I{} sh -c \
'export RUNFILE="{}" && clear && cargo run --bin $RUNFILE'
(TODO: Write up all the details of all the code)
I'm not sure how to pass the source_name
through clear via |
pipes. The solution I'm
using for that is to use a shell where I set an
environmental variable that gets read by cargo
after clear
wipes everything off the terminal.
It took some time to come up with that. And, frankly, I was nervous about trying to do it for reasons I can't really identify. But, I'm super glad I did. It's another example of working on something new that I'm uncomfortable with (xargs, in this case, specifically) and ended up with something that I'm really happy with and happy I powered through.