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.
show comments
sevensor
The Python stdlib does not get enough credit. People complain about things like how its http client is dated and slow, but it’s 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!
archargelod
If a script is simple - I use posix sh + awk, sed, etc.
But if a script I write needs to use arrays, sets, hashtable or processes many files - I use Nim[0]. It's a compiled systems-programming language that feels like a scripting language:
- Nim is easy to write and reads almost like a pseudocode.
- Nim is very portable language, runs almost anywhere C can run (both compiler and programs).
- `nim r script.nim` to compile and run (cached on subsequent runs) or use a shebang `#!/bin/env -S nim r`
- Nim programs are fast to compile (use debug mode and tcc compiler for almost instant compile times)
- Nim scripts run very fast <10ms (something that was very annoying to me with bash and Python)
- good chances you don't need external dependencies, because stdlib is batteries included and full of goodies.
- if you need external deps - just statically link them and distribute a cross-compiled binary (use zigcc[1] for easy Nim cross-compilation).
> 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.
show comments
mubou2
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:
I like the message the article is trying to convey, Python is good alternative to complicated shell scripts in my opinion.
I do wonder, let's say the scripting file is using lots of libraries, do you have to include some kind of requirements.txt file with it aswell when you want to share it with other people?
In Ruby, there is inline bundler which makes sharing a single Ruby script very portable.
I strongly agree with this.
At $WORK I usually work on projects comprising many small bits in various languages - some PowerShell here, some JS there, along with a "build process" that helps minify each and combine them into the final product.
After switching from shell scripts to Just and having to deal with a ton of issues on the way (how does quoting work in each system? How does argument passing? Environment variables?) I simply wrote a simple script with Python, UV shebang and PEP723 dependencies. Typer takes care of the command line parsing, and each "build target" is a simple, composable, readable python function that takes arguments and can call other ones if it needs to. Can't be simpler than that and the LLMs love it too.
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.
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.
binary132
I like using Go for “scripting”. To each their own I suppose.
show comments
kazinator
> By the way, don’t add a comma after the elements in the list, ...
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.
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:
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.The Python stdlib does not get enough credit. People complain about things like how its http client is dated and slow, but it’s 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!
If a script is simple - I use posix sh + awk, sed, etc.
But if a script I write needs to use arrays, sets, hashtable or processes many files - I use Nim[0]. It's a compiled systems-programming language that feels like a scripting language:
- Nim is easy to write and reads almost like a pseudocode.
- Nim is very portable language, runs almost anywhere C can run (both compiler and programs).
- `nim r script.nim` to compile and run (cached on subsequent runs) or use a shebang `#!/bin/env -S nim r`
- Nim programs are fast to compile (use debug mode and tcc compiler for almost instant compile times)
- Nim scripts run very fast <10ms (something that was very annoying to me with bash and Python)
- good chances you don't need external dependencies, because stdlib is batteries included and full of goodies.
- if you need external deps - just statically link them and distribute a cross-compiled binary (use zigcc[1] for easy Nim cross-compilation).
[0] - https://nim-lang.org
[1] - https://github.com/enthus1ast/zigcc
> 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.
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-...
I like the message the article is trying to convey, Python is good alternative to complicated shell scripts in my opinion.
I do wonder, let's say the scripting file is using lots of libraries, do you have to include some kind of requirements.txt file with it aswell when you want to share it with other people?
In Ruby, there is inline bundler which makes sharing a single Ruby script very portable.
https://bundler.io/guides/bundler_in_a_single_file_ruby_scri...
I strongly agree with this. At $WORK I usually work on projects comprising many small bits in various languages - some PowerShell here, some JS there, along with a "build process" that helps minify each and combine them into the final product. After switching from shell scripts to Just and having to deal with a ton of issues on the way (how does quoting work in each system? How does argument passing? Environment variables?) I simply wrote a simple script with Python, UV shebang and PEP723 dependencies. Typer takes care of the command line parsing, and each "build target" is a simple, composable, readable python function that takes arguments and can call other ones if it needs to. Can't be simpler than that and the LLMs love it too.
Xonsh is perfect for this: https://xon.sh
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.
Same, use Javascript for Scripting. https://github.com/gutenye/script.js
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.
I like using Go for “scripting”. To each their own I suppose.
> By the way, don’t add a comma after the elements in the list, ...
Python:
Why not use Perl?
Weren't we already?
Dupe: https://news.ycombinator.com/item?id=46176113
why not use perl?
Python for scripting honestly is Xonsh :)
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.