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

I can't really stand Bash's arcane syntax, it drains my brain power (and time of consulting manual) every time I have to work with it. Switching to Fish has been a breath of fresh air for me. I think some people who want to use only Bash need to open their conservative mind. All of my personal shell scripts now are converted to Fish. If I want to run some POSIX-compatible script then I just use `bash scripts.sh`

Of course Bash is ubiquitous so I use them whenever I can in the company. A golden rule for me is: if it has more than 50 lines then I should probably write in a decent programming language (e.g. Ruby). It makes maintenance so much easier.



Bash as a language is a downright bad. Especially the mess around `,",'. Fish is better is in this regard, however the syntax of Fish's string-related functions is unbearable. (I have a growing suspicion, with string-related functions, syntactically valid expressions can be constructed, which don't compile!)

However, neither Bash nor Fish were created with Composability in mind, which is a show-stopper for me.

IMO don't use Bash if the script is longer than 20 lines and don't use Fish if it's longer than 50. Use Python. If you want to use a proper(!) language use any LISP-Dialect like Babashka, Guile Scheme, Racket, etc. If you need Types have a look at Haskell-Scripting.

EDIT: To clarify, use Fish for its bling-bling capabilities, don't use it for scripting and configuring your machine(s).


This battle was lost a long time ago. Bash is the standard on most UNIX systems. If you change this reality, one might even start to try to think about writing in fish or some other new shell. But I will not even consider another shell for scripts that need to be run by other people.


POSIX shell is the standard, not bash.


That ship has sailed, because busybox ash and dash continually implement some of bash features and semantics, which come from ksh.

And OSH implements almost all of bash

That is, The posix shell spec is missing a lot of reality. It’s not very actively maintained, unfortunately

The canonical example is not having local vars, which basically every shell supports


> The posix shell spec is missing a lot of reality. It’s not very actively maintained, unfortunately

POSIX was primarily intended a descriptive specification, rather than a prescriptive.

That is, it attempted to document and standardize the common behaviour found on many platforms during the Great Unix Wars, rather than say "hey we thought of this great new thing and released a spec, go implement it!", which is more how, say, web standards work. I does/did have some of that, but it was never the main goal.

These days "whatever Linux does" is the de-facto standard, for better or worse, and the need for POSIX is much less.


That's just feature creep, eventually they will implement all features of bash, zsh, csh, fish, elvish, oil, HolyC and all other shells that emerge in the meantime.


"Everybody using some extensions" is not a contradiction to "The standard is the baseline".

> It’s not very actively maintained, unfortunately

Because that's how standards works. If there is enough interest a new standard will be made, but right now, bash isn't it.


I agree that POSIX is needing of a few small additions;

* local keyword * 2 or 3 variable expansion tricks (string replacement etc) * pipefail

But with those, I think the spec isn't too bad. I've been writing (imo) high-quality (and shellcheck compliant) shell scripts for a decade, and _always_ try to be as pendantic about being posix compliant where humanly possible. Sometimes things are a _little_ harder (no sarcasm here), but it's really quite doable once you get the hang of it.

You scripts then end up being far more portable, and as stated below, MUCH easier to read. The trick is, to write readable code (which is hard enough for most people, regardless the language anyway :p)

e.g. (a very simple example), and an addition to Shrikant's post, avoid the terse double ampersant 'and' (&&) and double pipe 'or' (||) operators, in normal calls. do e.g. ```sh if ! external_command; then do something with failure fi ``` Rather then `external_command || do something with failure`

These can get up becoming really hard to read once they become longer, where reading a stupid "if" statement is easy to comprehend. Readability over saving number of lines.

One important hint left forgotten, always make sure the last line of your file is `exit 0` or similar. This is more a 'weak' security feature. Prevent people from appending files and executing stuff instead. Gives a known exit point.

Another addition would be to actually favor single quotes for pure strings, and use double quotes where you expect the shell to do something with your string (true for most cases, but there's plenty of strings that benefit from single quotes, and hint the reader what to expect). Also integers should never be quoted (as it would turn then into strings), which shows a 'bad' example in the trace statement, you are now comparing the strings '0' and '1' rather then the number. Best use something easier to read in that case.

One thing I will pick up from this post for sure, is the trace hint, I'm adding that to my scripts, but probably a little more tunable.

```sh set -eu if [ -n "${DEBUG_TRACE_SH:-}" ] && \ [ "${DEBUG_TRACE_SH:-}" != "${DEBUG_TRACE_SH#"$(basename "${0}")"}" ] || \ [ "${DEBUG_TRACE_SH:-}" = 'all' ]; then set -x fi

echo 'Hello World'

exit 0 ``` Though I'll probably just settle for one of those keywords, I like 'all' the best atm. This would run the trace only if this special keyword is given, or if the variable contains the name of the script. I initially had `basename "${0%%.sh}"` but that makes things like `test,test1,test2` impossible, though that only helps if the extension is used ;)

While not needing be part of this list, I personally also always use functions, unless the script really is less then a handful lines, like google's bash-guide, always have a main etc.

In the end though I do disagree writing bash and bashisms. There's plenty of posts about that though; kind of like the whole C++ 'which version to use' discussion, where bash tends to be inconsistent in itself.

Shameless plug: See some of my older stuff here https://gitlab.com/esbs/bootstrap/-/blob/master/docker_boots...


Not going to install fish on all of my servers just so i can run your scripts, sorry. They already have bash pre-installed, though.

> If I want to run some POSIX-compatible script then I just use `bash scripts.sh`

Shouldn't you be using a shebang?


>Shouldn't you be using a shebang?

Why would they use a shebang? `bash script.sh` works perfectly fine. Ever used a terminal?


I use fish as an interactive shell but I don't write fish scripts. Once you accept a script has dependency there seems little reason not to go all the way to python (or usually I just go all the way to rust now, but I suspect others may disagree with me more on that than python)


If you are going to write in a language that requires installing additional dependencies on every machine, why not something like Lua? The great thing about bash for me is that it just works on most machines without dependencies.




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

Search: