In 35 years I've never been able to write more than ten lines of bash-level scripting without saying "Screw this, it's unreadable and unmaintainable" and writing the thing at hand in something else. (I think the longest non-trivial batch file I ever wrote was about 20 lines. I hated it). The "something else" changes with platform and decade, but usually it's native, or at least something like Python or C#.
Makefiles make me feel the same way, but here I have little choice. You can structure them "well" but they remain essentially undebuggable bits of hell that always seem to fall apart at the worst time.
I've worked with systems that had multi-thousand-line batch files and shell scripts, and my reaction has been "this crap is unsalvageable". A lot of those systems are still in production, and the people on them hate their lives. The code is a mass of spaghetti with a bunch of behavior modified by global and environment variables.
About 30 years ago I made the statement that "BASIC programs should self-destruct after 50 edits", as a way to encourage users of that language to move on to something more better, and to limit the damage that a "mission critical" 2 KSLOC hunk of bad code incurs. I maintain this would be desirable for bash and batch-like stuff, too...