Another tricky thing: recursively copying a folder is not easy to get right in an idempotent way due to arcane bash behaviors: https://unix.stackexchange.com/questions/228597/how-to-copy-...
How to write idempotent Bash scripts
171–180 of 195 posts
Re: How to write idempotent Bash scripts
#172Earlier quoted context omitted.
https://linux.die.net/man/1/flock would probably help
flock(1) is not POSIX, though. mkdir(1) can be used if you absolutely want a POSIX way to manage locks. For example: if ! mkdir .lock; then printf >&2 "Already running?\\n" exit 1 fi Some network file system implementation do not guarantee atomic mkdir, so you still need an extra caution with this method.
Re: How to write idempotent Bash scripts
#173The problem with the idempotent trend in configuration management is that it’s all based on not tracking or knowing what the current state of something is. So reasoning about how these systems work is fundamentally impossible. It would be better to focus on systems where by we can always know the state and improve the tooling there.
On the contrary. With idempotence you know the state after an action. rm -f will always delete the file (if possible). ln -sfn will always work, even for a directory. With the default behaviour of rm, ln -s, etc you know neither the state before, nor after.
Re: How to write idempotent Bash scripts
#174mountpoint -q $MOUNTPOINT || mount ...
Instead of
if ! mountpoint -q $MOUNTPOINT; then mount ... fi
It's much more compact in the case of having a lot of commands that need to be checked in case they don't need to be run again.
Re: How to write idempotent Bash scripts
#175Earlier quoted context omitted.
> An easy way to cover that is to have the script create a file, which you check at the start of the script and if present you exit. This does sound a good solution on paper, but "checking at the start" and "creating a file" are two different steps (i.e. not atomic) and will cause trouble eventually if your system has the tendency to run the script twice. A better solution is to use the `flock` command before creatin…
Within a shell script context, 'mktemp' and 'mv' are almost always what you want, possibly 'ln -s' for libraries. The first safely creates a temporary file. The second (with noclobber set or -n argument) will atomically rename a file, but not overwrite existing contents. Linux uses symlinks to system library files in order to allow in-place atomic replavement without affecting running processes with open filehandles…
Nope. If you rm a library, the processes using that library keep using the old library. Symlinks have nothing to do with it.
Re: How to write idempotent Bash scripts
#176Earlier quoted context omitted.
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 turnaroun…
Re: How to write idempotent Bash scripts
#177I like to use stuff like mountpoint -q $MOUNTPOINT || mount ... Instead of if ! mountpoint -q $MOUNTPOINT; then mount ... fi It's much more compact in the case of having a lot of commands that need to be checked in case they don't need to be run again.
mountpoint -q /proc || {
mount -t proc none /proc
chown 0400 /proc/slabinfo
}
if you need multiple statements.Re: How to write idempotent Bash scripts
#178Earlier quoted context omitted.
The -n flag keeps echo from emitting a line ending.
I used a distro in recent memory where `echo -n foo` really produced `-n foo`. The workaround was `printf "%s" foo`.
Re: How to write idempotent Bash scripts
#179Earlier quoted context omitted.
Well, sadly mktemp is not part of POSIX. So while it is available on a wide range of systems, there are also different implementations with different options. So while I like the job it does, I am also pretty disappointed how 'unportable' scripts become as soon as they use mktemp :-/
You can invoke mktemp(1) in ways that work across most contemporary systems. At least if you don't care that the resulting names are going to look a bit weird (have lots of XXXXXX in them due to name prefix vs. template differences among implementations).
Re: How to write idempotent Bash scripts
#180Earlier quoted context omitted.
Well, sadly mktemp is not part of POSIX. So while it is available on a wide range of systems, there are also different implementations with different options. So while I like the job it does, I am also pretty disappointed how 'unportable' scripts become as soon as they use mktemp :-/
It is sad to read these comments by people believing POSIX is something relevant today. My advice is to give up on false hope that POSIX will solve portability problems. POSIX ideas of shell are 30 years old and refusing to use anything newer alone won't make your script work correctly on all systems. If feasible, install bash, which has become the standard de facto . Or just write your script to test for the shell v…
Yes, ultimately you have to test your scripts on the actual systems, but that is something you have to do anyway. For example, when you run scripts on MacOS and you run into old Bash bugs because Apple refuses to ship an up-to-date version, those are issues a standard can't solve.
However, I have no experience how much you can count on POSIX when it comes to C APIs and the like.