Perhaps just wrap each preparation command in an if block? if { execline-cd data }
Will continue the script if execline-cd succeeds, and abort if it does not. On Mon, Sep 5, 2022, 1:54 PM Saj Goonatilleke via skaware < skaware@list.skarnet.org> wrote: > Hello, > > Within the context of, say, an s6 run script that needs to do a little bit > of > prep work before execing into a server, it is often helpful to abort early > if > any of said prep work stumbles upon an unexpected problem. > > Maybe the filesystem is R/O. Or full. > Maybe an operator has fat-fingered something we need. > Who knows! Production is full of surprises. > > sh provides set -e, which is often satisfactory for simple prep scripts > (if one is aware of its footguns). > > Is there a succinct, idiomatic set -e equivalent in the execline suite? > > I have included an example s6 run script below, which demonstrates the > closest I > have come so far. fgsigwait is my alternative take on foreground[1]. > fgsigwait > behaviour differs in the following respects: > > * fgsigwait exits[2] if prog1 exits with non-zero status. > foreground, by comparison, sets the ? environment variable and continues. > (fgsigwait -! reverts to foreground-ish behaviour.) > > * fgsigwait forwards some trappable signals to its child. HUP, INT, etc. > This is where its name comes from. > (PID 1 is broken on some of our systems, which provided the initial > motivation > for this hack. fgsigwait always waits on prog1 after forwarding a > signal. > This, plus execline's execution model, gave me fine control over when > stuff > is forked -- and helped us avoid some Z process leaks. Anyhoo.) > > fgsigwait otherwise aims to be a syntactic execlineb drop-in for > foreground in > cases where these features are desired. Chaining stuff with fgsigwait > emulates > sh set -e without needing to repeatedly and explicitly test the ? env var. > > --- 8< --- > #!/usr/bin/env -S execlineb -WP > > fdmove -c 2 1 > > # slow-deathroll is a simple wrapper around > # github.com/leahneukirchen/snooze > # extends the s6 one-second restart penalty if we crash too soon > fgsigwait { slow-deathroll } > > # Here is a simple example of some prep work. > # We want to bail here if any of these things exit non-zero. > fgsigwait { > execline-cd data > if -t { test ! -e live } fgsigwait { mkdir -p empty } ln -s empty live > } > > # maybe a smidge more prep here... > > # all prep done. exec into our server. > nsd -d -c nsd.conf > --- >8 --- > > This does work OK, but, every time I reach for my little program, I can't > shake > the feeling that I am probably reinventing some wheel. > > fgsigwait was implemented in Go, as is personal tradition when something > need be > hacked up in a hurry on the clock. Spooling up the Go runtime eats a few > extra > milliseconds of time, and a few megabytes of memory. While not practically > significant to us -- we don't deploy to tiny machines -- a small part of > me was > sad to add bloat. It would be nice if I could get rid of it. > > Is there a better way to abort? > > I suppose I could just fork sh, but inlining is pleasant when the prep is > short. > > Thanks! > > > [1]: https://skarnet.org/software/execline/foreground.html > [2]: https://skarnet.org/software/execline/exitcodes.html >