“exec-on-change”, a shell script to run a SolidPython program when the program changes

This page tells how to create and use “exec-on-change” to automatically run a SolidPython program each time you save the program. This makes it quick and easy to get feedback as you develop a CSG model. exec-on-change is as below. (You can download it from githubusercontent, and can see other Plastics files at github as well.)

# Detect when file named by param $1 changes.
# When it changes, do command specified by other params.
# Result of inotifywait is put in S so it doesn't echo
while  S=$(inotifywait -eMODIFY $F 2>/dev/null)
  printf "At %s: \n" "$(date)"

Put the shell-script text shown above in a file, exec-on-change, and make the file executable. (Eg, chmod +x exec-on-change). Then move the file to a directory that is on your search path. (For example, if you have a $HOME/bin directory on the search path, that’s a reasonable location.) To use the script, enter a shell command like exec-on-change program.py "python program.py" & where program.py stands for the name of the program you wish to monitor and execute. Each time program.py changes, the command python program.py will execute.

If your program produces output in, say, result.scad, you would also enter a command like openscad result.scad & and would turn on the “Automatic Reload and Preview” option on OpenSCAD’s ‘Design’ tab. Then, whenever program.py runs successfully, OpenSCAD will notice that its input file has changed, and will rebuild and redraw whatever the model is.

Here is what happens in the above script (skip to bolded sentence if not interested in technical details): the line F=$1 copies the first script parameter into shell variable F. Then shift discards the first parameter, so that variable P equals the rest of the parameter line. The line while S=$(inotifywait -eMODIFY $F 2>/dev/null) starts a while loop that runs as long as the file named by $F exists. The clause S=$(inotifywait -eMODIFY $F 2>/dev/null) waits for inotifywait to detect that file $F changed, discards any error messages, and stores its output into variable S. [The $(…) portion is shell-speak for “execute … and return the result”.] Each time a change occurs, the current time and date is printed to the terminal, and then the command contained in the last parameter is executed.

Note 1: If inotifywait isn’t already installed on your system, you may need to install it. See directions at the inotify-tools wiki. Eg, for Linux Ubuntu, apt-get install inotify-tools . The inotify system gets file-system event information from your OS only when relevant file system changes occur, rather than busy-waiting and constantly watching for changes.

Note 2: In using exec-on-change, you need to say python program.py instead of just program.py even if your program’s first line is (eg) #!/usr/bin/env python because a Text file busy shell error message will occur if you don’t.

Note 3: The exec-on-change command shown above — exec-on-change program.py "python program.py" & — ends with an ampersand, &. That makes the command work in the background; its output (from print) will appear in the terminal where you started exec-on-change, but that terminal can still be used for other commands. You can make the exec-on-change process stop via a command like kill p where p is the PID number of exec-on-change‘s process. You may wish to note the PID number displayed when exec-on-change starts, or can use the ps command later to find it out. If you aren’t comfortable with kill and ps commands, leave the ampersand (&) off the command, and press Ctrl-C when you want to end the process.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website with WordPress.com
Get started
%d bloggers like this: