Live data from Hacker News

Writing Safe Shell Scripts (2019)

sipb.mit.edu

1–10 of 166 posts

Re: Writing Safe Shell Scripts (2019)

#3
Shell scripts have their well-deserved place in Unix systems. A general recommendation to use Python or other high-level scripting languages without a discussion about the reasons why and when to use shell may lead to wrong conclusions.

Re: Writing Safe Shell Scripts (2019)

#5
Can mktemp fail? I recently wrote a script that ensures that the directory created by mktemp actually exists and starts with /tmp so that when the script wipes out its temporary data at the end, it will not ever run something like "rm -rf /". Using fully-qualified paths for everything is also (not) fun.

In another script I was leery about running rm -f -- /path/foo* so I instead used

  find /path -mindepth 1 -maxdepth 1 -name "foo*" -delete
because then the glob can't affect find's behaviour in weird ways.

Most likely set -e is enough protection against mktemp failing and the rm -f glob probably would've been just fine, but shell scripting has enough footguns that sometimes I can't help but go overboard with paranoia.

Re: Writing Safe Shell Scripts (2019)

#6
post #2

Make sure to have ShellCheck either integrated in your editor or run it before executing. It really tells many of the rules you're supposed to abide by and helps you write cleaner shell script. https://github.com/koalaman/shellcheck

Shellcheck is amazingly impressive at catching issues with shell scripts. It makes it very hard to write a shell script that does the wrong thing.

Also, look at oilshell[1]; it is bash compatible out-of-the-box, but has several options to make it incompatible, but safer (e.g. no field splitting of parameter expansion by default, making quotes much less needed).

1: https://www.oilshell.org/

Re: Writing Safe Shell Scripts (2019)

#7
Checking $PATH or explicitly calling outside resources is probably also advisible.

In general, this article seems very light. No mention of LD_LIBRARY_PATH, for example. I imagine there's probably a better guide to writing secure scripts somewhere else.

Re: Writing Safe Shell Scripts (2019)

#8
post #5

Can mktemp fail? I recently wrote a script that ensures that the directory created by mktemp actually exists and starts with /tmp so that when the script wipes out its temporary data at the end, it will not ever run something like "rm -rf /". Using fully-qualified paths for everything is also (not) fun. In another script I was leery about running rm -f -- /path/foo* so I instead used find /path -mindepth 1 -maxdepth…

> Can mktemp fail?

Yes it can. You should use its exit status (or set -e). See http://man.openbsd.org/mktemp

Note that there is a nasty trap if you're using local to declare and set a variable:

    a () { local M=`ls /asdf` && echo y; }
    b () {       N=`ls /asdf` && echo y; }
    a ; b ;
One will print y, the other will not.

Re: Writing Safe Shell Scripts (2019)

#9
post #5

Can mktemp fail? I recently wrote a script that ensures that the directory created by mktemp actually exists and starts with /tmp so that when the script wipes out its temporary data at the end, it will not ever run something like "rm -rf /". Using fully-qualified paths for everything is also (not) fun. In another script I was leery about running rm -f -- /path/foo* so I instead used find /path -mindepth 1 -maxdepth…

Yes, mktemp can fail.

For example, "TMPDIR=/dev/null mktemp -d" will reliably fail.

You shouldn't be validating it starts with "/tmp" though, because on quite a few systems, people set TMPDIR=/var/tmp.

You absolutely should check if mktemp exited nonzero, but if it exited 0, the directory should be safe to use. If you want to be really paranoid, you can check if the output is an empty string too after checking the exit code.

I think you're shying a little too far away from bash's globbing. Yeah, bash has footguns, but using clever workarounds can also be a recipe for creating confusing and error prone code in its own way.

Re: Writing Safe Shell Scripts (2019)

#10
post #9
post #5

Can mktemp fail? I recently wrote a script that ensures that the directory created by mktemp actually exists and starts with /tmp so that when the script wipes out its temporary data at the end, it will not ever run something like "rm -rf /". Using fully-qualified paths for everything is also (not) fun. In another script I was leery about running rm -f -- /path/foo* so I instead used find /path -mindepth 1 -maxdepth…

Yes, mktemp can fail. For example, "TMPDIR=/dev/null mktemp -d" will reliably fail. You shouldn't be validating it starts with "/tmp" though, because on quite a few systems, people set TMPDIR=/var/tmp. You absolutely should check if mktemp exited nonzero, but if it exited 0, the directory should be safe to use. If you want to be really paranoid, you can check if the output is an empty string too after checking the ex…

Please tell me it's enough to check the exit code! That's all I ever do and I have hundreds of mktemp scripts out there.

In the end I think shelling is mostly about controlling your inputs.

Post reply on HN