Show HN: Attempt – A CLI for retrying fallible commands

github.com

67 points by maxbond 3 days ago

Hi HN,

Here's a tool I wrote for retrying fallible commands. Nothing groundbreaking here, this is a tool that's been made many times (and several have been submitted to Show HN). Though this one does have a more comprehensive feature set than most. I hope one or two people will find it useful.

I wrote `attempt` for two reasons:

- To have a more featureful alternative to `wait-for-it.sh` for use in Docker Compose. Specifically to apply migration scripts to a database that may not be up yet. I wanted to be able to inspect the error messages from my migration tool & retry on connection errors.

- To test a hypothesis I had that a good way to make a CLI was to copy the API of a good library (in this case, `tenacity`). I want to write a blog post at some point to discuss this at length, but the tl;dr is that I believe it was a success.

Here are some usage examples: https://maxbondabe.github.io/attempt/usage.html

There may not be much to discuss for such a small tool, but I am open to all feedback and am happy to answer any questions.

Cheers,

Max

NightMKoder 3 days ago

I was recently in the market for one of these! I ended up going with https://github.com/dbohdan/recur due to the nice stdout and stdin handling. Though this has stdout/stderr pattern matching for failures which is nice too!

  • maxbond 3 days ago

    Cool, I hadn't seen this one yet! Using Starlark is a very good idea. I ended up writing some tiny DSLs to specify certain things like status code patterns and durations; using an off the shelf DSL like Starlark would've saved a lot of effort.

    • bharrison 3 days ago

      Very nice work!

      I am very far from expert, but understood expect: https://linux.die.net/man/1/expect to be the "swiss army knife" for this type of thing.

      • maxbond 2 days ago

        I'll confess I've never used `expect`, but I think `expect` is for interactive commands. I think if you were going to write retry logic in bash you would pipe it to `grep` and examine the return code. If `grep` doesn't find any matches, it'll exit with a status code of 1.

        I'd never heard of the `wish` command shell (discussed briefly in that document) but you can always rely on the Tcl community to find a great pun.

nickdothutton 2 days ago

I am reminded of the lack of really strong batch/job control of the sort I enjoyed as far back as VAX VMS at university, anything that brings a stronger capability to modern OS is welcome. This is I think a big missing thing.

brirec 3 days ago

This is kind of neat. I appreciate how well it falls into the whole Unix philosophy of small tools that do one thing really well.

One thing I’m kind of curious about from a UI standpoint is why the exponential argument isn’t a double-hyphen flag. It kind of feels like it should be, given all of the other arguments are flags.

  • maxbond 3 days ago

    Thanks! That was the intention. There's a tool called `retry` which does an even better job by caching stdin so that it can be integrated into shell pipelines.

    I was thinking of it as a subcommand, like `git pull`. I think of the backoff schedules as different "modes" the command can be put into, each with their own set of arguments. I also made some questionable design decisions and coupled too closely to the CLI argument parser (`clap`), which would make it a big pain to back out of that decision.

jalk 3 days ago

This is useful. Don't want to think about how many times I have implemented retrying in shell scripts. I appreciate the extensive documentation, but I would suggest adding the output of `attempt --help` to the README / docs, so that features can be discovered at a glance.

  • maxbond 2 days ago

    Thank you for the suggestion. It's a reasonable one. I'm undecided. The --help output is pretty long, I don't want to put so much information in the README that it damages it's legibility. But you're right that the documentation is maybe too dense for easy discovery. I'll add it to the docs shortly, but for the README I'm going to keep thinking about it for now.

    I've created an issue: https://github.com/MaxBondABE/attempt/issues/5

juliangmp 3 days ago

This looks nice Maybe I can finally replace that sshtry shell function which I've been using for a few years

lloydatkinson 2 days ago

> `wait-for-it.sh` for use in Docker Compose.

Any time I hear people praising all these orchestrators, whether it's Docker, K8, or whatever, I remember that a good amount of it is all lies built with glue and sticks like "wait-for-it.sh".

dannyobrien 3 days ago

This great! Thank you for writing it.

  • maxbond 3 days ago

    Thanks! Glad you like it!

adastra22 3 days ago

Is “try” taken as a CLI command? Seems like a better name.

  • maxbond 3 days ago

    That would be a good name. If it's taken it's not in the Debian or Arch repositories. I've been working on this on and off for a couple years, so I honestly don't remember why I picked `attempt`.