> We have vastly better tools now in those niches.
But do we? I'll beg to differ.
Python explodes in to LoC when you try to attempt to work with the OS. You need to source modules that turn the application in to bloat. 98% of def's you don't require.
If you need a multi-purpose tool, or a model than sure. For the simple automation of running a rsync or ZFS snapshot schedule to copy to & from a NAS in a guaranteed timely manner in cron, it works just fine. The overhead of using languages compared to the previous is partly why I keep using bash or Tcl.
For anything more complex than linear shell scripting, I prefer ruby --disable-gems these days. As you say, Python is horrible for composing and executing shell commands, but Ruby's FileUtils#sh (combined with %W{} array literals, %x{} output capturing and regular #{} string interpolation) provides a pretty low-impedance interface.
> > We have vastly better tools now in those niches.
> But do we? I'll beg to differ.
We do. I mentioned Fish and PowerShell for interactive scripting. Those definitely handle your rsync/zsh snapshot case. If you're OK installing software, xonsh and nushell seem interesting; I briefly played with the latter and it seemed really nice. As usual, bash/zsh/dash win on ubiquity, but ubiquity and quality are utterly disconnected. For heavier languages/Perl-alikes, Lua's not a bad contender here and tends to be widely installed. Ruby, too, is a near-ubiquitous improvement on Bash and Perl, but it emulates the latter more than my personal preference, and is inferior to Python 3 when it comes to uniformity of behavior across versions and included batteries. I think tcl's suboptimal here because it's no longer part of a lot of Linux distros, but it's fine.
Nitty aside: for cron jobs specifically, I find that it's rarely worthwhile to deal with a multi-line shell script: either I can run a single shell-wrapped command directly with output-file redirection, or I go all the way to a language with proper error stacktraces (since about 80% of my simple-cron-job-debugging work tends to be of the "figure out how far it made it before silently crashing" variety). And that's again because of the awful shell default of on-error-resume-next, one of many trash behaviors of bash/sh.
And yeah, the shell is a very easy way to set up cron output capturing; wish it didn't come with all the other warts. If something like "tee" or "xargs" had a single-line invocation form which did everything that "bash -eu[x]c 'rsync <whatever>; echo done' >output.log 2>err.log" does, I'd switch to that in a heartbeat. If you want something outlandish like, I dunno, timestamps on those log lines, well ... enjoy learning about FD substitution or double-escaping awk in a pipe or something (after you shake off the hangover from realizing that you'll have to double-wrap shell invocations because cron only invokes POSIX sh). Yuck.
Hell, so long as I'm saying contentious things that shouldn't be, ideally you'd ditch the cron and use the ubiquitous tool that was explicitly built to work around those exact shortcomings of the shell and cron itself: a systemd timer.
> Python explodes in to LoC when you try to attempt to work with the OS.
Python's ubiquitous and popular, and some extra LoC/uniform copy-paste imports are a trade I and many people gladly make in exchange to not having to worry about rare, niche issues like "what keysmash do I type to get the length of an array" or "what arguments does this function take" or "am I getting the exit code of the last thing that ran, or the intermediate 'grep' I ran on its output". If that trade's distasteful, you can take on a third-party library and get terseness back using something like plumbum. But really, most bash/perl vs python arguments that revolve around line count and verbosity (or whitespace) aren't arguing about whether the tool is capable, they're arguing about aesthetics. Sure, the car's an ugly color, but it drives better.
> You need to source modules that turn the application in to bloat. 98% of def's you don't require.
I don't know what you mean by this. You can "from sys import argv"; you shouldn't "from sys import *". And you're rarely "paying" much to import/compile all the other symbols in the module; most of the modules you'd need for basic shell scripting are either part of the interpreter core or already imported at Python startup anyway. If you don't like even that tiny overhead, well, I have bad news for you about what Perl does when you 'use strict', or what the OS does when Bash makes you launch a subprocess of tail/grep/cat/whatever just to parse a command's output.
Edits: posted the first half early by mistake then added discussion of cron/import cost.