[HN Gopher] Use Python for Scripting
___________________________________________________________________
Use Python for Scripting
Author : birdculture
Score : 32 points
Date : 2025-12-08 08:52 UTC (4 days ago)
(HTM) web link (hypirion.com)
(TXT) w3m dump (hypirion.com)
| zahlman wrote:
| Dupe: https://news.ycombinator.com/item?id=46176113
| mubou2 wrote:
| 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-...
| eternityforest wrote:
| What 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.
| mubou2 wrote:
| Well, 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-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 wrote:
| UV 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 wrote:
| It's amazing what happens when something just works.
| jollyllama wrote:
| I 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 wrote:
| There'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 wrote:
| >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 wrote:
| You 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....
| simonw wrote:
| This 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 wrote:
| I wish env -S was more portable. It's a newer feature of
| the coreutils env implementation and isn't supported
| elsewhere afaik.
| collinfunk wrote:
| FreeBSD 6.0 added 'env -S'. They have adopted a few
| different GNU inspired options recently, which I am happy
| about.
| presbyterian wrote:
| As someone who writes a lot of python, I love uv, but isn't
| on nearly every system like python is, which is one of the
| arguments for using python here in the first place
| Rucadi wrote:
| Nix allows you to do this with any language and required
| dependency: https://wiki.nixos.org/wiki/Nix-shell_shebang
| albertoCaroM wrote:
| Whoa! 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.
| milliams wrote:
| 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 wrote:
| > How do you handle packages?
|
| The same way you handle them with bash?
|
| Install them?
|
| What are we talking about here?
| fridder wrote:
| I 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
| a-dub wrote:
| what can you do with bash that you cannot do with the python
| standard library and shelling out?
| kjkjadksj wrote:
| What is wrong with writing a short wrapper in bash to activate
| a conda env before running the script? Too unsexy?
| DonHopkins wrote:
| Isn'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.
| N_Lens wrote:
| Weren't we already?
| sevensor wrote:
| The Python stdlib does not get enough credit. People complain
| about things like how its http client is dated and slow, but its
| pretty amazing that it's just right there if you need it, no
| external dependencies needed. And it's sitting right next to
| difflib, graphlib, pathlib, struct, glob, tkinter, and dozens of
| others. Sure, every one of these is limited individually, but
| those limitations are stable and well understood!
| rjmill wrote:
| Odd, I don't see any mention of subprocess.run, the workhorse of
| python scripting.
|
| Quick rundown for the unfamiliar:
|
| Give it a command as a list of strings (e.g.,
| subprocess.run(["echo", "foo"]).)
|
| It takes a bunch of flags, but the most useful (but not
| immediately obvious) ones are: check=True: Raise
| an error if the command fails capture_output=True: Captures
| stdout/stderr on the CompletedProcess text=True:
| Automatically convert the stdout/stderr bytes to strings
|
| By default, subprocess.run will print the stdout/stderr to the
| script's output (like bash, basically), so I only bother with
| capture_output if I need information in the output for a later
| step.
| tayo42 wrote:
| Pretty much anything longer then a throwaway one liner I write in
| python.
|
| Would be cool if python had a pipe operator though.
|
| The back ticks in ruby is pretty ergonomic too. Wish python had a
| simpler way to run commands. Kind of tedious to look up
| subprocess run arguments and also break things up into arrays.
| davidkhess wrote:
| Xonsh is perfect for this: https://xon.sh
| abhiyerra wrote:
| I have been converting a lot of my makefiles to pyinvoke and
| fabric and it makes things so much easier to manage than bash or
| make. Don't know why I held on for so long.
| Rendello wrote:
| I've never liked shell scripting. Last year, I switched my build
| system of a Rust project over to Python (Cargo is actually quite
| limited as a build system). For a newer project, I'm using Rust
| itself with the XTask pattern. I'm not sure if I prefer the
| Python or Rust approach yet.
| kkfx wrote:
| Python for scripting honestly is Xonsh :)
| gabrielsroka wrote:
| > Python is installed on pretty much every machine
|
| > Python 3 is installed on basically every machine out there.
|
| > Python will work the same on all the machines you run your
| script on
|
| No, no, and no.
___________________________________________________________________
(page generated 2025-12-12 23:02 UTC)