Hazel is a centrepiece of my automation suite on macOS. I rely on it to watch directories and take complex actions on files contained within them. Recently I discovered an issue with files that are locked in the Finder. If files that otherwise match all the rules are locked, then Hazel will attempt to execute the rules. But the locked status may preclude execution. For example, I began seeing frequent Hazel notifications popups such as:
Unable to execute the Move action on the matched file, Hazel gives up with a Notification. Instead I would prefer that it not match the file in the first place. But how to do that? There’s no criterion for locked/unlocked file status. Even extended criteria in the “Other…” list seems to have no option for this.
The solution is to use a Passes shell script condition in our rule, using the following script:
ls -lO "$1" | grep -q "uchg" && exit 1 || exit 0
- The file to be tested is passed to the script as
$1and we are expected to exit with
0if the file matches and non-zero if the file does not match.
lscommand on Unix system lists directory contents. If we pass a file to
lsthen is returns only the information about that file. So
ls "$1"would just provide basic information about the file. To find any flags on macOS we need two options. The first option
-lgives us access to the long format and the
-Oflag provides file flags. We compress these options into
- The flag we’re looking for is
uchgso we pipe the
grepwhich tries to match the
uchgflag. We use the
-qbecause we don’t care about the contents of the matching line; we just want to know whether it matches or not.
- Finally we exit with
1(failed match) if
uchgis present and
0if absent. This way files that are locked do not match.
If you have the macOS developer command line tools installed, you will have
getfileinfo installed and you could also use that to find the locked status of a file. For example running
getfileinfo -aL "my_unlocked_file" will return 0. Whereas running it on a locked file will return 1.
Possibly there’s a simpler way to accomplish this; but for now this is what I’m going with. Enjoy.
lsman page for macOS - everything you wanted to know about