I only use Bash for the simplest tasks. For anything more elaborate I use Groovy scripts. At some point I switch to full Groovy projects, switching on static compilation, adding unit and integration tests and so forth.
If you let your Apache Groovy scripts get too large before switching on static compilation, you often have to modify the types and logic in your programs before they'll even compile. This problem occurs because static compilation was only bolted onto Groovy for version 2.0 and there's an impedance mismatch between what's required for its dynamic and static modes.
Error handling, edge cases, unit tests, type checking, packaging can all be performed in Python.
Type checks are the biggest bug bear. Otherwise, it’s relatively easy to get things clean and tidy (packaged).