Telling Hazel not to match locked files
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
Explanation
- The file to be tested is passed to the script as
$1
and we are expected to exit with0
if the file matches and non-zero if the file does not match. - The
ls
command on Unix system lists directory contents. If we pass a file tols
then is returns only the information about that file. Sols "$1"
would just provide basic information about the file. To find any flags on macOS we need two options. The first option-l
gives us access to the long format and the-O
flag provides file flags. We compress these options intols -lO
. - The flag we’re looking for is
uchg
so we pipe thels
results togrep
which tries to match theuchg
flag. We use the-q
because 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) ifuchg
is present and0
if absent. This way files that are locked do not match.
Extra
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.
References
ls
man page for macOS - everything you wanted to know aboutls
on macOS