You've probably seen the #!/usr/bin/env -S uv run pattern popularized by Simon Willison.
One issue I've had with it: When "upgrading" scripts to get their own pyproject.toml, I can't run them from a different directory anymore!
E.g. this works:
./my_script.pyThis doesn't:
some_dir/my_script.shThis special, but longer, shebang header allows us to do that.
It works like this:
- The first line is a shebang executing the file as a regular old POSIX script with /bin/sh.
- A comment follows - this is ignored by sh (and also python)
- Here comes the magic: We start a python block comment.
- in Bash land, we just gave an empty string (
""), followed by the start of a string ("). - to make bash happy, we finish off with
:" - turning that "start of a string" into "please execute
:" - which is an alias for "true"`, or a no-op command returning 0
- in Bash land, we just gave an empty string (
- Now, we just tell bash to run
uv, but with--project $(dirname $0), so that UV knows where to search for a pyproject file. - We use
execto replace the runningsh, so that signals and return codes are followed - We use
set -euto error out if any errors occur before uv takes over
- unset variables
uvnot being installed, etc.
Tested on
- macOS
- Debian (Bookworm)
Probably doesn't work on Windows, unless you're using WSL or Git-Bash.