Live data from Hacker News

Safe ways to do things in bash

github.com

21–30 of 255 posts

Re: Safe ways to do things in bash

#21
post #17
post #5

> POSIX mandates /bin/sh Nope. On the contrary, it says: Applications should note that the standard PATH to the shell cannot be assumed to be either /bin/sh or /usr/bin/sh Source: http://pubs.opengroup.org/onlinepubs/009695399/utilities/sh.... A pedantically-compliant shell script should not have shebang at all.

What's wrong with `#!/usr/bin/env sh`?

POSIX doesn't include shebang (#!) at all. It should, but it currently doesn't.

Re: Safe ways to do things in bash

#22

Earlier quoted context omitted.

> You are source controlling your shell scripts right? My personal heuristic for shell scripts are that if I care enough about them to put them under source control, they shouldn't be a shell script.

Do Makefiles fall under that category?

Chiming in for myself, no. Makefiles are more about dependency graphs and reproducible pipelines. I use them to make more sophisticated things than bash scripts, which are purely imperative.

I very much dislike cmake, and I've not yet been impressed by any of the other many Make replacement candidates.

How else would you accomplish what a Makefile would?

Re: Safe ways to do things in bash

#24
post #8

From the article: > Should I use curly braces? Bad: some_command $arg1 $arg2 $arg3 Extra bad (cargo culting unnecessary braces): some_command ${arg1} ${arg2} ${arg3} Correct: some_command "${arg1}" "${arg2}" "${arg3}" Better: some_command "$arg1" "$arg2" "$arg3" > In the "extra bad" and "correct" examples, braces compete with quotes under the limits of tolerable verbosity. > Shellharden will rewrite all these variant…

Honest question: what happens when the variable has a quote in it? If FOO is ‹xyz"; rm -r *; "xyz› (where I've used ‹› as delimiters) then won't even "${FOO}" expand to multiple arguments/commands? Or does bash automatically escape the quotes in the situation?

Both of those examples end up being fine. When quoted the entire variable is passed as a single WORD and the shell won't interpret the `;` as the end of the command. Even without quoting the variable it would be fine in this case because of where you've put the quotes, though you should still quote the variables. As a simple illustration take a look at the following:

    function e() {
        echo $#
    }
    $ x="hello world"
    $ e $x
    2
    $ e "$x"
    1

Re: Safe ways to do things in bash

#25

Earlier quoted context omitted.

> You are source controlling your shell scripts right? My personal heuristic for shell scripts are that if I care enough about them to put them under source control, they shouldn't be a shell script.

Do Makefiles fall under that category?

I haven't used them enough to have an opinion because of questions like these, which I need time to answer for myself.

Re: Safe ways to do things in bash

#26
post #12

Earlier quoted context omitted.

Sometimes you just want some 30-50 lines of piping a few commands and a couple of conditionals. Python (the language with the most community traction to replace bash for scripts) is a royal pain to use for this without libraries that are present in no default system, and even with those it often ends up being more verbose than it should.

> Sometimes you just want some 30-50 lines of piping a few commands and a couple of conditionals. maybe I was not clear - nothing against shell-scripting but doing some weird dancing like in the article is imho useless, also depending on bash is a stupid idea imho. posix sh + shellcheck is all you need. if you can't solve your problem in posix sh rethink your code / approach and simplify until it will work.

[deleted]

Re: Safe ways to do things in bash

#27
post #2

If you reached a point where you need to require bash and not a posix shell and need to enforce these rules just use python or lua if you can or some scheme or whatever else... it's not worth the wasted time hunting bash cruft. if you are on busybox with ash none of this is helping (except shellcheck which is great).

Sometimes you just want some 30-50 lines of piping a few commands and a couple of conditionals. Python (the language with the most community traction to replace bash for scripts) is a royal pain to use for this without libraries that are present in no default system, and even with those it often ends up being more verbose than it should.

For typical system scripts, ansible is much better than bash. It has all the commands that are missing from Unix and it's not subject to the bash problems mentioned here.

I agree that python is a pain. It's too low level for any task.

Re: Safe ways to do things in bash

#28
post #8

From the article: > Should I use curly braces? Bad: some_command $arg1 $arg2 $arg3 Extra bad (cargo culting unnecessary braces): some_command ${arg1} ${arg2} ${arg3} Correct: some_command "${arg1}" "${arg2}" "${arg3}" Better: some_command "$arg1" "$arg2" "$arg3" > In the "extra bad" and "correct" examples, braces compete with quotes under the limits of tolerable verbosity. > Shellharden will rewrite all these variant…

> You are source controlling your shell scripts right? My personal heuristic for shell scripts are that if I care enough about them to put them under source control, they shouldn't be a shell script.

Straight from teenage wisdom on freenode ##linux circa 2003

Re: Safe ways to do things in bash

#29
Interesting stuff, but given bash's

- Relative unportability - Poor noncompliant sh interpreter - Poor performance (can be 4x slower than POSIX sh shells like dash for certain tasks)

I personally think bash is always the wrong choice. Use POSIX sh (or a real language). POSIX sh is 98% the same thing, there's no good reason to even use bash over sh in the vast majority of cases. It's just this blight that won't go away.

Given that bash is mostly sh anyway, most of this writeup applies to sh, too. AFAIK the only thing bash-specific here is arrays.

Re: Safe ways to do things in bash

#30
Most of this is fine, but not all. In particular, command failure conditions are a huge source of bugs, but `set -euo pipefail` is not going to solve all your problems. `set -e` is just as likely to cause problems because it can cause scripts to silently fail. And pipefail can pass through errors that aren't relevant.

These are great tools to have, but don't blindly invoke them as magic spells if you don't actually understand the implications.

Post reply on HN