Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

BASH is like Obi Wan. It isn’t the most powerful or flashiest, but it survived a long time, where others didn’t, for very good reasons. Bash runs basically everywhere. It has many modern features you wouldn’t expect. Its syntax is literally what you would type on the command line if you were diagnosing or fixing systems so you don’t need to transpile to another language. Its reliance on other programs means it is glue and can easily incorporate highly cohesive functionality/tools others write and maintain. Also, it’s been around and is everywhere so you don’t worry about trying to incorporate the current latest and greatest declarative tool (which will blow over in 5 years) into your other workflows. Basically, don’t disparage a Jedi/tool that has survived where others didn’t. There is a reason.


Also, use shellcheck. Incorporate it into you editor. Fix all warning and don’t ignore them. This will push you deep into bash syntax rabbit holes but you come out better the other side.


A lot of bash errors are not understanding possible cases due to white space.. which shellcheck catches. After using it for a while, I don’t even really worry about white space because of the good habits I’ve learned/(been forced to use).


That's all well and good until you come across a filename with a linefeed in it - null termination is where it's at!

(I can't actually recall encountering a filename that includes a linefeed)


I've got several empty files on my desktop (on Windows) serving as sticky notes of some sort, and they have line breaks in their names, obviously.


I didn't even know that Windows supported that, but I try to keep away from it as much as possible. Makes for an interesting test of scripts, I suppose. Sometimes, I script BASH to cope with any any filenames, but it depends on the usage as a lot of the time you can guarantee that files will be at least semi-sensible.


Find the problem:

  echo "$(tr -dc A-Za-z0-9 </dev/urandom | dd count=1 bs=16 2>/dev/null)"
       ^-- SC2005 (style): Useless echo? Instead of 'echo $(cmd)', just use 'cmd'.
I have experienced so many situations where shellcheck is giving harmful advice or warns me about the thing that is exactly my intention.


The style issue shellcheck reports here is probably what we both suspect it is.

The call to echo has a likely purpose is to trim some spaces from a string, but it's not at all obvious why this is done or what the benefit is. In the best case, it leaves the reader pondering this weird semi-no-op.

If you think shellcheck, and probably most readers, is wrong in this assertion, just speak your mind and let's learn from one another. But I certainly can't guess your intention here.


I would probably do it this way:

tr -dc A-Za-z0-9 </dev/urandom | dd count=1 bs=16 2>/dev/null; echo

A few less characters to type, you get your newline, and shellcheck doesn't complain.


Using "echo" at all is a problem. It's recommended to switch to "printf" instead as echo has unfixable problems, especially with strings that start with a dash.

  printf "%s\n" "$(tr -dc A-Za-z0-9 </dev/urandom | dd count=1 bs=16 2>/dev/null)"
If you don't require the line feed, then you can just use:

  tr -dc A-Za-z0-9 </dev/urandom | dd count=1 bs=16 2>/dev/null


The thing with echo is repeated again and again but not a problem in the code i've just posted (due to A-Za-z0-9).

And i do require the line feed. Following shellcheck's advice broke the code.


Not a problem until the random string starts with a dash and you get unexpected results from "echo" interpreting it as an option instead of an argument. Using "printf" bypasses that issue as it's clear what the argument is.

Just tested it and ShellCheck is happy with the printf version:

  printf "%s\n" "$(tr -dc A-Za-z0-9 </dev/urandom | dd count=1 bs=16 2>/dev/null)"
It's also got a stylistic improvement (in my opinion, anyhow) in that the line feed is explicit in the printf command rather than being almost a side effect of echo.

Edit: I see your point about the "tr" not enabling a dash, so my example falls a bit flat, but my point stands in other scenarios. It's good practise to avoid echo where feasible. I think the double quotes will also protect in this instance. The problem with relying on the tr string to not foul up echo is that you may later adapt the code and use a different translate string which could then introduce a tricky bug to track down.


I'd also add that in the cases where you disagree with shellcheck (it doesn't get everything correct all the time), you can include a disabling comment just before the line to tell shellcheck that you know best:

# shellcheck disable=SC2005


…what’s the problem?


Also maybe check out the bash language server.

https://github.com/bash-lsp/bash-language-server/


Also, familiarise yourself with https://mywiki.wooledge.org/BashPitfalls


So if Bash is like Obi Wan surviving where other didn't....

Is Bash just surviving because no one knows about it or has remembers it while its been hiding in your system for 20 years?


Also, what will it be like as a Force ghost?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: