Am I crazy in thinking that bash is good enough for production?
Badland9085 @ Badland9085 @lemm.ee Posts 1Comments 159Joined 2 yr. ago
That’s my take on the use of bash too. If it’s something that people think it’s worth bring their pitchforks out for, then it’s something you should probably not write in bash.
To each their own really. You have what you’re familiar with, and I have mine. That said, I’m not proposing Bash as a good language. It is by no means that.
Now, to use Python for comparison. With a year of not using it, I’d be asking lots of questions. How do I mkdir
? How do I mkdir -p
? What about cp
or mv
and their flags? Did I use to bring in some library to make this less painful?
Cause look, I already use many of these commands in the terminal, basically all the time cause I work in it.
Fwiw, there’s a bash-language-server
that can warn you of some syntactical errors.
That is definitely not something I would do… for work (totally not implying that I miiiight do it outside of work for shits and giggles :P).
I didn’t create this post trying to be like “y’all should just use Bash”, nor is it an attempt to say that I like Bash, but I guess that’s how people boil others down to these days. Fanatics only. Normalcy is dead. (I’m exaggerating ofc)
I’m so glad we have madlads in rust land xD Thanks for referring me to that!
Your experiences are based on your familiarity with other languages. It may or may not apply to others. So to each their own I guess?
I do agree that the square bracket situation is not best though. But once you know it, you, well, know it. There’s also shellcheck to warn you of gotchas. Not the best to write in, but we have linters in most modern languages for a reason.
I actually like bash’s variable expansion. It’s very succinct (so easier to write and move onto your next thing) and handles many common cases. The handling is what I hope most stdlibs in languages would do with env vars by default, instead of having to write a whole function to do that handling. Falling back is very very commonly used in my experience.
There are cases where programming is an exercise of building something. Other times, it’s a language, and when we speak, we don’t necessarily want to think too much about syntax or grammar, and we’d even invent syntaxes to make what we have to say shorter and easier to say, so that we may speak at the speed of thought.
That’s definitely worth mentioning indeed. Bash variables, aside from arrays and hashmaps that you get with declare
, are just strings. Any time you need to start capturing a group of data and do stuff with them, it’s a sign to move on. But there are many many times where that’s unnecessary.
To be fair, you don’t always have to use the [[
syntax. I know I don’t, e.g. if I’m just looking for a command that returns 1 or 0, which happens quite a bit if you get to use grep
.
That said, man test
is my friend.
But I’ve also gotten so used to using it that I remember -z
and -n
by heart :P
I can only imagine that macro crate being a nightmare to read and maintain given how macros are still insanely hard to debug last I heard (might be a few years ago now).
I find this argument somewhat weak. You are not going to run into the vast majority of those errors (in fact, some of them are not even errors, and you will probably never run into some of those errors as Postgres will not return them, eg some error codes from the sql standard). Many of them will only trigger if you do specific things: you started a transaction, you’ll have to handle the possible errors that comes with having a transaction.
There are lots of reasons to never use bash to connect to a db to do things. Here are a couple I think of that I think are fairly basic that some may think they can just do in bash.
- Write to more than 1 table.
- Write to a table that has triggers, knowing that you may get a trigger failure.
- Use transactions.
- Calling a stored procedure that will raise exceptions.
- Accepting user input to write that into a table.
One case that I think is fine to use bash and connect to a db is when all you need to do a SELECT
. You can test your statement in your db manager of choice, and bring that into bash. If you need input sanitization to filter results, stop, and use a language with a proper library. Otherwise, all the failure cases I can think of are: a) connection fails for whatever reason, in which case you don’t get your data, you get an exit code of 1, log to stderr, move on, b) your query failed cause of bad sql, in which case, well, go back to your dev loop, no?
This is why I asked what sort of problems have you ran into before, assuming you haven’t been doing risky things with the connection. I’m sorry, but I must say that I’m fairly disappointed by your reply.
I’m going to read this with a big “/s” at the end there xD
As one other comment mentioned, unfamiliarity with a particular language isn’t restricted to just bash. I could say the same for someone who only dabbles in C being made to read through Python. What’s this @decorator
thing? Or what’s f"Some string: {variable}"
supposed to do, and how’s memory being allocated here? It’s a domain, and we aren’t expected to know every single domain out there.
And your mention of losing typing and structure information is… ehh… somewhat of a weird argument. There are many cases where you don’t care about the contents of an output and only care about the process of spitting out that output being a success or failure, and that’s bread and butter in shell scripts. Need to move some files, either locally or over a network, bash is good for most cases. If you do need something just a teeny bit more, like whether some key string or pattern exists in the output, there’s grep. Need to do basic string replacements? sed or awk. Of course, all that depends on how familiar you or your teammates are with each of those tools. If nearly half the team are not, stop using bash right there and write it in something else the team’s familiar with, no questions there.
This is somewhat of an aside, but jq is actually pretty well-known and rather heavily relied upon at this point. Not to the point of say sqlite, but definitely more than, say, grep alternatives like ripgrep. I’ve seen it used quite often in deployment scripts, especially when interfaced with some system that replies with a json output, which seems like an increasingly common data format that’s available in shell scripting.
How easily can you start parsing arguments and read env vars? Do people import clap and such to provide support for those sorts of needs?
I find it disingenuous to blame it on the choice of bash being bad when goalposts are moved. Solutions can be temporary as long as goalposts aren’t being moved. Once the goalpost is moved, you have to re-evaluate whether your solution is still sufficient to meet new needs. If literally everything under the sun and out of it needs to be written in a robust manner to accommodate moving goalposts, by that definition, nothing will ever be sufficient, unless, well, we’ve come to a point where a human request by words can immediately be compiled into machine instructions to do exactly what they’ve asked for, without loss of intention.
That said, as engineers, I believe it’s our responsibility to identify and highlight severe failure cases given a solution and its management, and it is up to the stakeholders to accept those risks. If you need something running at 2am in the morning, and a failure of that process would require human intervention, then maybe you should consider not running it at 2am, or pick a language with more guardrails.
Could you explain those db connection hiccups you’ve seen?
What do you suppose bash could do here? When a program reaches some critical mass in terms of adoption, all your bugs and features are features of your program, and, love it or hate it, somebody’s day is going to be ruined if you do your bug fixes, unless, of course, it’s a fix for something that clearly doesn’t work in the very sense of the word.
I’m sure there’s space for a clear alternative to arise though, as far as scripting languages go. Whether we’ll see that anytime soon is hard to tell, cause yeah, a good lexer and parser in the scripting landscape is hard work.
If you need anything that complex and that it’s critical for, say, customers, or people doing things directly for customers, you probably shouldn’t use bash. Anything that needs to grow? Definitely not bash. I’m not saying bash is what you should use if you want it to grow into, say, a web server, but that it’s good enough for small tasks that you don’t expect to grow in complexity.
I don’t necessarily agree that all simple tasks will lead to the need for a test suite to accommodate more complex requirements. If it does reach that point,
- Your simple bash script has and is already providing basic value.
- You can (and should) move onto a more robust language to do more complicated things and bring in a test suite, all while you have something functional and delivering value.
I also don’t agree that you can just solder on whatever small task you have to whatever systems you already have up and running. That’s how you make a Frankenstein. Someone at some point will have to come do something about your little section because it started breaking, or causing other things to break. It could be throwing error messages because somebody changed the underlying db schema. It could be calling and retrying a network call and due to, perhaps, poorly configured backoff strategy, you’re tripping up monitoring alerts.
That said, I do agree on it suitable for temporary tasks.
Those two libraries actually look pretty good, and seems like you can remove a lot of the boilerplate-y code you’d need to write without them. I will keep those in mind.
That said, I don’t necessarily agree that bash is bad from a maintainability standpoint. In a team where it’s not commonly used, yeah, nobody will like it, but that’s just the same as nobody would like it if I wrote in some language the team doesn’t already use? For really simple, well-defined tasks that you make really clear to stakeholders that complexity is just a burden for everyone, the code should be fairly simple and straightforward. If it ever needs to get complicated, then you should, for sure, ditch bash and go for a larger language.
Somewhat unfair judgement against emails IMO, especially cause it’s the “trust list” that’s in the control of a few, with no open manner to add more people to the trust list. The protocol isn’t at fault for failing to prevent problems; it’s the ability for corporations to gain significant market share without control, before they are then allowed to put barriers down to disallow or discourage interaction between those in and out, forcing those within to stay in, while those outside to give up on others in order to gain usability.
This is almost a strawman argument.
You don’t have to shell out to a db cli. Most of them will gladly take some SQL and spit out some output. Now that output might be in some tabular format with some pretty borders around them that you have to deal with, if you are about the output within your script, but that’s your choice and so deal with it if it’s within your comfort zone to do so. Now if you don’t care about the output and just want it in some file, that’s pretty straightforward, and it’s not too different from just some cli that spits something out and you’ve redirected that output to a file.
I’ve mentioned in another comment where if you need to accept input and use that for your queries, psql is absolutely not the tool to use. If you can’t do it properly in bash and tools, just don’t. That’s fine.
With web API calls, same story really; you may not be all that concerned about the response. Calling a webhook? They’re designed to be a fire and forget, where we’re fine with losing failed connections. Some APIs don’t really follow strict rules with REST, and will gladly include an “ok” as a value in their response to tell you if a request was successful. If knowing that is important to the needs of the program, then, well, there you have it. Otherwise, there are still ways you can get the HTTP code and handle appropriately. If you need to do anything complex with the contents of the response, then you should probably look elsewhere.
My entire post is not to say that “you can do everything in bash and you should”. My point is that there are many cases where bash seems like a good sufficient tool to get that simple job done, and it can do it more easily with less boilerplate than, say, Python or Ruby.