Live data from Hacker News

How to do things safely in Bash (2018)

github.com

1–10 of 98 posts

Re: How to do things safely in Bash (2018)

#2
I've recently taken to not bothering with shell scripts at all. I just use Python instead. The type system, while it's by no means state of the art, is still miles ahead of the stringly-typed bash. The libraries are excellent; much can be done with the standard library alone. The scripts are much faster (even though the language isn't particularly tuned for performance), since I don't need to spawn a subprocess for each little string manipulation task. And if I ever need to ‘shell out’ to an external process, there's always the subprocess module that is much more robust than ‘set -e’ ever was.

Seriously, if you can avoid it, just don't write shell scripts at all. Use a real programming language instead.

Re: How to do things safely in Bash (2018)

#3

I've recently taken to not bothering with shell scripts at all. I just use Python instead. The type system, while it's by no means state of the art, is still miles ahead of the stringly-typed bash. The libraries are excellent; much can be done with the standard library alone. The scripts are much faster (even though the language isn't particularly tuned for performance), since I don't need to spawn a subprocess for e…

All the deployment things are just wrappers to shell commands so if you want to help people debug user-data.sh, cron, ansible, docker files, or puppet, you need to understand shell. Also, it is better to have something in bash as code than not have it be fully automated. I draw the line at arrays tho. If you want arrays don’t do bash. But if you want to just run a bunch of commands on your compute, bash is there.

One thing I have started doing for stuff that need to go via ssh is I just do a here doc for an embedded shell script that I scp to the remote and then just use ssh to invoke it. The quoting and pseudotty stuff just got to be too dumb to understand.

Also, and maybe this is just for non-interactive scripts, I find everything from writing them to using them is a lot easier if you take pains to make them idempotent, so you can run them one or 100 times with the same effect.

Re: How to do things safely in Bash (2018)

#5
If you’re interested in writing safe shell scripts then check out shellcheck:

https://github.com/koalaman/shellcheck

If you’re interested I’ve written a git hook for it that runs a check when you git commit:

https://github.com/alblue/scripts/blob/main/shellcheck-pre-c...

You should also check out her Google shell script style guide:

https://google.github.io/styleguide/shellguide.html

Re: How to do things safely in Bash (2018)

#6
The fact that you have to use quoting nearly everywhere is a design flaw in the Borne shell. Some shells, like Plan 9's rc, for example, don't expand after variable substantiation. They have an operator to call if you want to explicitly force expansion. That's so much cleaner and less error prone.

Re: How to do things safely in Bash (2018)

#7

I've recently taken to not bothering with shell scripts at all. I just use Python instead. The type system, while it's by no means state of the art, is still miles ahead of the stringly-typed bash. The libraries are excellent; much can be done with the standard library alone. The scripts are much faster (even though the language isn't particularly tuned for performance), since I don't need to spawn a subprocess for e…

> The [python] scripts are much faster...

Pipelines are performant; many algorithms can be expressed as pipelines. Bash has many built-in string manipulation mechanisms which do not require a sub shell.

Why do people who subscribe to the “avoid shell scripts at all costs” ideology feel so passionately about prescribing to others?

I like python, but if I am in a rush it’s shell.

Re: How to do things safely in Bash (2018)

#8

I've recently taken to not bothering with shell scripts at all. I just use Python instead. The type system, while it's by no means state of the art, is still miles ahead of the stringly-typed bash. The libraries are excellent; much can be done with the standard library alone. The scripts are much faster (even though the language isn't particularly tuned for performance), since I don't need to spawn a subprocess for e…

100% agree. This article should just be "rewrite your script in Python". It's not the best scripting language ever, but it works fairly well and it's about 100 times better than Bash.

Re: How to do things safely in Bash (2018)

#9
post #6

The fact that you have to use quoting nearly everywhere is a design flaw in the Borne shell. Some shells, like Plan 9's rc, for example, don't expand after variable substantiation. They have an operator to call if you want to explicitly force expansion. That's so much cleaner and less error prone.

zsh is also doing the variable substitution better than bash. FYI, I just released rust_cmd_lib 1.0 recently, which can do variable substitution without any quotes: https://github.com/rust-shell-script/rust_cmd_lib

Re: How to do things safely in Bash (2018)

#10
post #6

The fact that you have to use quoting nearly everywhere is a design flaw in the Borne shell. Some shells, like Plan 9's rc, for example, don't expand after variable substantiation. They have an operator to call if you want to explicitly force expansion. That's so much cleaner and less error prone.

Oil is Bourne compatible, but has a mode to opt you into the better behavior. Example:

    osh$ empty=''
    osh$ x='name with spaces.mp3'
This is like Bourne shell:

    $ argv $empty $x
    ['name', 'with', 'spaces.mp3']   # omit empty and split

    $ argv "$empty" "$x"       
    ['', 'name with spaces.mp3']     # unchanged
Opt into better behavior, also available with bin/oil:

    $ shopt --set oil:basic

    $ argv $empty $x                                                                                 
    ['', 'name with spaces.mp3']  # no splitting/elision
If you want to omit empty strings, you can use the maybe() function, which returns a 0 or 1 length array for SPLICING with @:

    $ argv @maybe(empty) "$x"
    ['name with spaces.mp3']      # omitted empty string
Example of splicing arrays:

    $ array=("foo $x" '1 2')

    $ argv $empty @array
    ['', 'foo name with spaces.mp3', '1 2']
This is called "Simple Word Evaluation": https://www.oilshell.org/release/latest/doc/simple-word-eval...

Feedback appreciated!

(Interestingly zsh also doesn't split words, but it silently removes empty strings).

Post reply on HN