11 ms·
My take is that bugs in sh scripts are best avoided by not programming in sh. So my preferred tool for sh linting is git-rm. It's not always possible, but drivi
by lolc 3y ago
My take is that bugs in sh scripts are best avoided by not programming in sh. So my preferred tool for sh linting is git-rm. It's not always possible, but driving down the sh line count sure helps against bugs from this language and its weird expansion rules.
Most people don't even know the language has expansion rules and write stuff that accidentally works after the fourth try. This lang wants to become obsolete.
- dimitar 3y agoI agree, but some bash can be unavoidable. I've found that even trivial looking bash can be helped with shell-check; this is a testament to the issues in bash more than anything.
- jzwinck 3y agoWhat bash is unavoidable? The aliases and functions you define in your personal shell, sure. But what else?
- auselen 3y agoPiping stuff, job control?
- dimitar 3y agoSome examples of possible exceptions: * Installing or starting your general-purpose runtime, passing the right configuration options * Project glue where introducing general purpose language makes things more complicated because of tooling or startup. * Simple cloud-init scripts * A command line tool is simply the best library for the job and you don't want to get a general purpose language just to immediately shell out.
- jjgreen 3y agoEasy to avoid, use POSIX sh. It is a truth universally acknowledged that 95% of bash scripts don't use any non-Bourne features (or can trivially be modified to be so).
- BaculumMeumEst 3y agoWhat on earth? POSIX sh is far more annoying to deal with than Bash. The only reason anyone puts up with it is to target the lowest common denominator. Horrible advice.
- synergy20 3y agothere are many cases that you have to use sh scripts, e.g. many IoT devices, embedded devices etc where python etc are just huge and slow.
- uxp8u61q 3y agoIf you wouldn't program it in Python, you wouldn't program it in sh either. You don't run shell scripts on embedded devices! Typically, an embedded device runs one program that basically acts as the whole OS for the device. There's no kernel or userspace to speak of. You're directly interfacing with the hardware, and that's it.
- pletnes 3y agoThis just isn’t true. Smart TVs run some linux/android, so do car infotainment, the list goes on. Old tumble dryers, vacuum cleaners - sure.
- uxp8u61q 3y agoThese appliances can run python scripts just fine, then. Try to read the whole context instead of focusing on one part of the comment. I'm writing in the context of an appliance that can't run python script. That means the resources are heavily constrained.
- bluGill 3y agoBash is usful for 100 lines scripts that do little logic and mostly chain together various commands. Setup the right CC variables and call make.
- paulddraper 3y agoOkay, let's say that you want a script that counts the number of lines in files versioned by git. You'd write a Python3 script I assume? With subprocess?
- jzwinck 3y agoToy examples should not guide larger decisions. And even if that trivial script you describe is really what goes into production today, tomorrow someone will modify it and introduce a quoting bug or a poorly-done command line option facility or whatever.
- paulddraper 3y agoHuh? What makes this a plaything? Did you respond to the right comment?
- jzwinck 3y agoYou asked about: > a script that counts the number of lines in files versioned by git I'm saying that is not a realistic production program that most of us would need. If you want it as a personal utility to use in your own shell, absolutely you can use bash. I'm responding to the idea that such a trivial script would have long term use in production.
- deleted 3y ago[deleted]
- paulddraper 3y agoAh I didn't know the original comment was about "production"
- jenscow 3y agoTo mitigate that, recently there was something posted on HN that checks your shell script for those types of bugs. However, let's not produce any software at all, in case someone introduces a bug in it later.
- tgv 3y agoDon't use bash, don't use C, don't use C++, don't use Python, don't use Javascript, don't use Ruby, ...
- paulddraper 3y agoDon't use computers. Only winning move
- fooker 3y agoThere are two kinds of languages, ones that everyone complains about, and those that nobody uses.
- devnullbrain 3y agoEveryone uses Python
- spoiler 3y agoPeople complain about various python and its ecosystem's quirks all the time, though!
- devnullbrain 3y agoYou don't need to use its ecosystem at all to use it as a replacement for sh
- theonemind 3y agoI complain about Python all of the time. 1. seems to frequently get used for large products where people should really do strong static typing 2. Python 2 to 3 fiasco 3. Packaging and venvs and dependencies are a mess. 3a. versioning of dependencies. culturally handled in a slapdash kind of manner. 3b. Managing multiple versions of Python on my system, and multiple venvs per version. 4. not a functional language 5. Insanely, ridiculously slow compared to something like C. Slow even by the standards of scripting languages. 6. Python culture doesn't seem to acknowledge that regular users that don't care at all what language you used and want an executable, not a hot-glue build-your-own-environment hobby kit. 7. Pervasive culture of weak backward compat in libraries. 8. The pip devs are opinionated, and frankly user-hostile in my opinion, breaking backward UX convention, deprecating, general high-handed ivory-tower dev behavior. 9. I'd complain about the GIL, and a lot of people do, but I actually personally don't care. Maybe I covered it with the slow runtime and care indirectly. Every time I encounter something written in Python I just mentally groan and roll my eyes. I genuinely don't like Python. Some of what I enumerated obviously bleeds into culture and ecosystem, but in practical terms for practical use, that's not so cleanly separable from the language in a lot of cases. Perl was always great about backwards compat and documentation, Ruby had a strong web dev bent because of rails, blahblah.
- justapassenger 3y agoIf you have to interact with console tools, nothing beats bash. If you don’t have to, you should never use it.
- Alupis 3y agoOne does not program in bash. It is a scripting language - there's a difference, even if subtle. Just like any other tool, commit the time to learn it instead of just complaining it's hard. Developers tend to think they can write amazing things with minimal effort and then curse the tool/lang when things turn out different. The world runs on C and bash scripts... and it's just fine.
- lolc 3y ago> commit the time to learn it I did. Turns out I don't like it. What I dislike the most is that it brings out the clever type who likes to show off their tricks. That includes me. I've written atrocious Bourne scripts, and I've watched other people defend line noise in code reviews. > instead of just complaining it's hard So what's good about it that I should tolerate the weird expansions and arcane scoping? > The world runs on C and bash scripts... Less and less, thankfully. > and it's just fine. It may have been fine in 1980.
- deleted 3y ago[deleted]
- rollcat 3y agoCame here to say this exactly. My toy OS has the most spartan shell imaginable (no pipes, no redirection, no variables, no flow control, just run a list of commands). It's enough to mount filesystems, configure network interfaces, spawn some services, and do the reverse for shutdown. Complex tasks are delegated to Lua scripts or actual binaries instead.
- sigwinch28 3y agoI strongly agree with this. I find that I'm okay with shell scripts which invoke repetitive individual commands, run complex piped commands, or run a sequence of commands with little-to-no control flow. However, then I find that people use shell scripts for more advanced programming "because it's there" and "it's ubiquitous". What follows is a lot of stringly-typed programming using more and more bash-specific features and advanced control flow. External commands and builtins gather exotic flags to handle whitespace (or preferably null bytes). Then people want complex data types so they resort to things like `jq` and JSON stored in variables. But hey, at least they didn't use Python or Ruby! Some people argue that by using a programming language like Python or Ruby or Go instead of "just a shell script" that I then bring about dependency management hell because I might use non-stdlib libraries and I require a minimum version of the language. But the people writing shell scripts rely a lot on their ambient system environment that they take for granted. They will use bash instead of sh and assume a recent version of it (good luck macOS users!). They will assume that the coreutils are BSD or GNU and they will get it wrong. They will want advanced data structures and assume you have some random utility for manipulating JSON, CSV, or TSV installed. Now you have a dependency management problem just like you would in other programming languages. So then people say in a slack channel "hey, please install this util on your system", or they share Brewfiles and dockerfiles and container images, or they write yet another script to check your system for the right dependencies. You end up with a library of scripts and functions which require certain env vars to be set so they can all find and `source` each other. People writing and committing clever and complicated shell scripts usually end up with the same problems they would have with a different programming language that has package managers. But it's weeks or months down the road and it's easy not to think about when committing a 100 line bash script to the repo or adding new functionality to a script or depending on "just one more" installed utility. It devolves to the same problem of "I'm writing Python/Ruby/Haskell/C/C++/... and I'm relying on the operating system's package manager to provide the libraries I depend on", but without having a powerful general purpose programming language with an import system and featureful standard library. Some teams do that and shell scripts which rely heavily on the system environment might be a great fit for them. The best use case I can think of for shell scripts are FreeBSD init scripts, but then I consider how tightly coupled those are to the operating system. So basically... part of the system. I don't think I have the discipline for all of that, so my flowchart for writing shell scripts is: is it a one-liner? If yes, do it. If not, use the same programming language as the rest of the project(s) in your team.