Multiline shebang with zsh and running pyenv under cron
3 minutes read | 500 words by Ruben Berenguel
These probably qualify as the most one weird trick I have figured out this year.
Basically this is an answer to how can I configure configure the Python environment in the shebang? Like, say, to start a virtual environment. You can find many examples with bash here. But, how do you use it with zsh? And what it is?
It is text after a shebang expression in a script that is run by zsh, while eventually running the rest of the code. It feels a bit like a quine.
I faced this when writing my own provider script for Tip (a very recommended small app for Mac). Although it may not be required, but was fun as a problem to crack. The issue was twofold: I needed to run it under zshand I wanted to run my script under a virtual environment.
What is this? First, this is going to be executed as a zsh script. So, we have
an empty string,
a string containing true, which evaluates via expansion to true, inside quotes, so, another empty string.
Now some normal shell commands, load some scripts to prepare an environment. This .pyenvzshrc is a reduced .zsh without any configuration and just there so pyenv works as expected.
Disable the painful notification from pyenv
Runs python (the python from the correct environment), on this script itself with the same arguments
Exit! This is important! This way nothing else is seen by zsh. It has to exit in error to prevent the shell seeing the rest.
A commented line (shebang)
A triple-quoted string, which is then automatically added as the module docstring
Modification of the docstring for consistency
Neat, isn’t it? (not)
Running pyenv in cron
This is a repeated issue I have faced: running things under cron fails for… shell reasons. I wanted to run bear-note-graph regularly, to always have my note graph fresh on iCloud. The goal is similar to the previous: running Python in a specific virtual environment.