Live data from Hacker News

How to write idempotent Bash scripts

arslan.io

131–140 of 195 posts

Re: How to write idempotent Bash scripts

#131

This is generally terrible advice. A better option is to 'set -e' and ensure that the bash script exits when there's a failure. Bash scripts can't be idempotent because they operate in an external environment that can't ever be. The better option is to just be extra safe. See: > http://redsymbol.net/articles/unofficial-bash-strict-mode/

I agree. using -f is a poor excuse for not handling errors properly. imagine doing that in any other language.... oof

Re: How to write idempotent Bash scripts

#132

Earlier quoted context omitted.

What do you use to compute the diff? Just the diff command itself on individual files?

diff -R You can use numerous tools to compare/manage branches; md5sum / shasum (md5 is usually useful, though not entirely safe), diff and kin, vimdiff, rsync, fdupes, jdupes, git, hg.

I went the „git” way once and I found it really cool! With all the goodies you get for free from git, like applying patches, checking differences, resetting to previous state etc.

Re: How to write idempotent Bash scripts

#133

This is generally terrible advice. A better option is to 'set -e' and ensure that the bash script exits when there's a failure. Bash scripts can't be idempotent because they operate in an external environment that can't ever be. The better option is to just be extra safe. See: > http://redsymbol.net/articles/unofficial-bash-strict-mode/

I'm not sure why people see errors as a bad thing. Errors are good. They stop you from doing stupid things. But maybe this article is good for telling people why you should handle errors well or when you write code to make sure it fails gracefully. Because if you don't people are going to start telling others to use the force flag when removing (almost always a terrible idea).

Learn to handle errors, don't learn to brute force your way through them.

Re: How to write idempotent Bash scripts

#134
post #83
post #57

I think Python is getting so popular & ubiquitous now I can't see any reason to write bash scripts any more except for perhaps very simple ones that are just a few lines. Other people's bash scripts are regularly just too difficult and complex to maintain.

If you’re into minimal docker images, bash or similar shell might be the only script interpreter available. Python might not exist on your windows machine. Etc.

> Python might not exist on your windows machine.

Bash might not exist either.

Re: How to write idempotent Bash scripts

#136
post #126
post #50

Earlier quoted context omitted.

Yeah, I find out-of-the-box cookbooks about as helpful as out-of-the-box docker images: useful as a starting place but to leverage chef you really need to write your own. Chef resources/providers are nicely composable and the primitives are pretty easy to rewrite if you want, my main point is that chef gets you to think in terms of convergence instead of brittle imperative changes. You could rewrite your bash scripts…

My comment tried to argue that Chef's convergence is nothing more than a well hidden imperative thing. I agree that manipulating existing machines is folly, but that's why people use containers, and immutable images. And then you can prepare the images anyway you like, but since they are very deterministic (modulo the external repositories/packages/curl-bash-piped-scripts), you usually use something simple (eg bash),…

Fair enough, most of my experience is with a sort of homegrown chef-solo. It has served us pretty well for almost ten years but these days we're in the process of moving to kubernetes + immutable infrastructure.

Re: How to write idempotent Bash scripts

#137
post #44

Earlier quoted context omitted.

Writing a shell script in rust would be obnoxiously difficult for no real benefit.

Yeah, and tools like Chef are 99% blocked on disk operations anyways, so I have no idea why GP thinks Rust would help

CM systems spend a lot of time on bootstrapping, creating their workspace, downloading the scripts, parsing them, etc.

Then they simply execute other programs to then parse their output. And/or fiddle with files (parse them, alter them, write them).

Sure fundamentally the syscalls and apt/dnf/yum will be the slow parts, but I found that development of CM scripts/plays/recipes are usually bottlenecked on the turnaround time of the CM system's own workflow. And execution time is a significant part. (The bootstrap, the transfer of whatever files, and so on.)

Rust would help with writing things that are relatively well error handled at compile time, and gives you single binaries.

Re: How to write idempotent Bash scripts

#138
post #80
post #4

Many people who write scripts do not factor the environment they are run in and miss including traps to handle events like being terminated mid-way thru and cleaning up to a sanitized state. After all, creating a file, you can't presume their is enough free space, but people do in scripts all the time. Then you have scripts that you want run once and if run again not have any more effect. FOr example a script to be r…

Just have a database table, and update it with a special key. When the transaction commits, you know the script has executed correctly, and the key is written as a result. When the script doesn't complete, the commit is not performed, and you can run the script again. No need for "idempotent" scripts. Trying to do this with a filesystem instead of a real database, and things get messy.

You still have to make that messy choice between at-most-once and at-least-once execution of each transactionally guarded section.

Re: How to write idempotent Bash scripts

#139
post #80

Earlier quoted context omitted.

Just have a database table, and update it with a special key. When the transaction commits, you know the script has executed correctly, and the key is written as a result. When the script doesn't complete, the commit is not performed, and you can run the script again. No need for "idempotent" scripts. Trying to do this with a filesystem instead of a real database, and things get messy.

You still have to make that messy choice between at-most-once and at-least-once execution of each transactionally guarded section.

The idea is that you run the entire script as a single transaction. Then you only have to check for a key once (which is trivial).
Post reply on HN