5 ms·
How do you handle packages? I want scripts to a be a single file with a shebang, not a repo with a requirements.txt that I need to run in a venv. To me, this is
by _jzlw 10mo ago
How do you handle packages? I want scripts to a be a single file with a shebang, not a repo with a requirements.txt that I need to run in a venv. To me, this is the biggest blocker to using Python for any non-trivial scripting (which is precisely the kind where I wouldn't want to use bash), but I'd like to know how others deal with it.
C# scripts let you reference packages in a comment at the top of the file, for example:
https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app/ https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...
- eternityforest 10mo agoWhat can you do with bash that isn't in the stdlib of python? Generally the only nontrivial scripting I ever do is associated with a larger project, so I often already have a pyproject.toml and a UV environment, and I just add the dependencies to the dev group.
- _jzlw 10mo agoWell, that's kind of what I mean. For scripts in a python project, you can freely use whatever packages you need. But for one-off scripts, if you need bs4 or something, you're screwed. Either your script now has external dependencies or it requires special tooling. It just feels strange that C# of all languages is now a better scripting tool than Python, at least out of the box. I did notice uv has exactly the feature I'm looking for, though it's obviously third-party: https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies https://docs.astral.sh/uv/guides/scripts/#declaring-script-d... Is everyone just using uv now instead of pip, perhaps? Or is just another alongside pipenv, conda, poetry, etc.? (Python's not my main these days, so I'm out of the loop.)
- eternityforest 10mo agoUV is taking over really fast, it seems to be much more popular any other option. I suspect conda still has some market share too but I've never needed it.
- psunavy03 10mo agoIt's amazing what happens when something just works.
- jollyllama 10mo agoI don't understand. To return to GP's point, what can you do in bash that you can't do in Python? Said in another way, what does bash offer that you would need to tackle with a dependency in Python? My understanding is that there is no such thing, and accordingly, you can still end up with something that is better than bash if you just use Python and call out to other tools with subprocess.
- dizhn 10mo agoThere's bash. Then you need better loops/conditionals and more usable structures. That's when one should think of using a scripting language instead. I think the parent goes too far after that and what he's talking about is not something bash can do (well). That said, a lot of very complicated things are actually written in bash. Distrobox I think is for example.
- DonHopkins 10mo ago>That said, a lot of very complicated things are actually written in bash. Distrobox I think is for example. They're only complicated BECAUSE they're written in bash. If they were written in Python they would be much less complicated, more modular, able to use many existing industrial strength well tested python modules instead of rolling their own ad-hoc ones, and much easier to maintain.
- chillaranand 10mo agoYou can specify requirements at the top of file and uv can run the script after automatically installing the dependencies. https://avilpage.com/2025/04/learn-python-uv-in-100-seconds.html https://avilpage.com/2025/04/learn-python-uv-in-100-seconds....
- simonw 10mo agoThis works really well in my experience, but it does mean you need to have a working internet connection the first time you run the script. # /// script # dependencies = [ # "cowsay", # ] # /// import cowsay cowsay.cow("Hello World") Then: uv run cowscript.py It manages a disposable hidden virtual environment automatically, via a very fast symlink-based caching mechanism. You can also add a shebang line so you can execute it directly: #!/usr/bin/env -S uv run --script # # /// script # dependencies = ["cowsay"] # /// import cowsay cowsay.cow("Hello World") Then: chmod 755 cowscript ./cowscript
- emidln 10mo agoI wish env -S was more portable. It's a newer feature of the coreutils env implementation and isn't supported elsewhere afaik.
- collinfunk 10mo agoFreeBSD 6.0 added 'env -S'. They have adopted a few different GNU inspired options recently, which I am happy about.
- networked 10mo agoYou can use so-called "exec magic" instead of `env -S`. Here is an explanation with Python examples: https://dbohdan.com/scripts-with-dependencies#exec-magic https://dbohdan.com/scripts-with-dependencies#exec-magic (disclosure: my site). In short: #! /bin/sh "exec" "/usr/bin/env" "uv" "run" "--quiet" "--script" "$0" "$@" # /// script # dependencies = [ # "cowsay", # ] # /// import cowsay cowsay.cow("Hello, world!") On systems that can't run uv, like NetBSD and OpenBSD, switch to pipx: #! /bin/sh "exec" "/usr/bin/env" "pipx" "run" "$0" "$@" # ...
- Rucadi 10mo agoNix allows you to do this with any language and required dependency: https://wiki.nixos.org/wiki/Nix-shell_shebang https://wiki.nixos.org/wiki/Nix-shell_shebang
- albertoCaroM 10mo agoWhoa! This is a revelation. I already loved Nix and used nix-shell extensively, but this is the missing piece: fully reproducible Python scripts without compromise.
- luz666 10mo agoOr install direnv and put your dependencies into a shell.nix, setup the bash hook according the manual, create the .envrc with the content "use nix". Then type "direnv allow". Then you can do e.g. use other persons python scripts without modifying their shebang.
- HumanOstrich 10mo agoNow you have to set up Nix first and deal with that nightmare of a learning curve. Just to auto-install some dependencies for a script. Might as well rewrite all your scripts in Rust too while you're layering on unholy amounts of complexity.
- Diti 10mo agoIt’s like Vim, you learn it once, and you keep using it forever once you’re used to it. I’m so thankful to see a flake.nix file in every single cool project on code forges.
- HumanOstrich 10mo agoYea that's a common theme of excuses for both Rust and Nix. Wrong though, because most anyone who can use a computer at all can learn the basics of Vim. Seeing that flake.nix badge of complexity lets me know a project will be a nightmare to set up and will break every other week. It's usually right next to the Cargo.toml badge with 400 dependencies underneath.
- milliams 10mo agohttps://peps.python.org/pep-0723/ https://peps.python.org/pep-0723/, e.g.: # /// script # requires-python = ">=3.11" # dependencies = [ # "requests<3", # "rich", # ] # /// import requests from rich.pretty import pprint resp = requests.get("https://peps.python.org/api/peps.json") data = resp.json() pprint([(k, v["title"]) for k, v in data.items()][:10])
- paulddraper 10mo ago> How do you handle packages? The same way you handle them with bash? Install them? What are we talking about here?
- fridder 10mo agoI think it is the fact that python packaging has been problematic for some time. setuptools/easy_install, pip/pipx, poetry, conda, uv all promise they will be the thing that "fixes" it
- paulddraper 10mo agoWhat does Bash use for its packaging? Use that.
- bccdee 10mo agoOk tbh bash uses the system package manager to install command-line utilities, and using the system package manager for python packages HAS been tried, and the parallel use of system packaging and independent package managers is part of why python package distribution is such a mess.
- skydhash 10mo agoWhy using independent package managers alongside the system one? I think the introduction of non system packagers is what brought us the whole mess we are in. Most system packagers allows for custom repositories.
- bccdee 10mo agoBecause the system package repository doesn't package everything & isn't always up to date. And if you introduce other repos to fix this, then you have an ecosystem with multiple instances of the same package distributed at different versions in different repositories, and God help you if you need multiple versions of one package, or if you need a different version of Python entirely. Nix could do it, but not anything else. No—system python is for the system's scripts, and user projects should have their dependencies sandboxed in a virtual environment. That's the only model that really works.
- a-dub 10mo agowhat can you do with bash that you cannot do with the python standard library and shelling out?
- kjkjadksj 10mo agoWhat is wrong with writing a short wrapper in bash to activate a conda env before running the script? Too unsexy?
- DonHopkins 10mo agoIsn't the fact that bash doesn't have a wonderful ecosystem of reusable modules a much more enormous insurmountable problem than the fact that you have to install python modules? You're really missing the forest for the trees. Not only does bash not have a module system like python, or a vast ecosystem of modules like python, but also that it's much too weak and brittle a language to implement most of those modules that Python has, and can't even call native code libraries directly. Even with just its standard built in "batteries included" libraries and no extension modules or native code modules, Python is still much more powerful than bash and easier to code and maintain. If you're complaining about having to install Python modules, you're usually already doing something that's impossible or incredibly difficult to do in bash anyway. Even something as simple and essential as fetching files via http or parsing json. Bash has to call out to other programs to do that, but you have to install those programs too, and while Python can certainly call out to curl or wget or jq, it doesn't have to, since it has all that and more built in. There really is no comparison, because bash loses along so many dimensions at once compared to Python.
- froh 10mo agoIsn't pipx addressing exactly that? once the script is non-trivial, 'install' it using pipx, in editable mode when you work on the script and as normal pipx installed cli utility otherwise. the venv part is then completely under the hood.
- lgas 10mo agoI don't have much need of this personally, but I was playing around with an example from earlier in the thread and ended up with this: #!/usr/bin/env -S uv run --with sh --script from sh import ifconfig print(ifconfig("en0")) which is a pretty nice experience assuming you already have `uv` in the target environment.
- bigstrat2003 10mo agoHonestly, I just use a requirements.txt file. It's not as convenient as having a single file, it's true, but that is far outweighed by how much easier Python is to use than bash. So I'm giving up a 3/10 convenience but gaining a 10/10 convenience, which I think is worth it.
- qznc 10mo agoMy principles is that I do not. If PyPI packages are needed, rewrite it in Rust (or Go or D or whatever allows me to use statically-linked libraries). Python packages are fine for servers but not for CLI tools.