{"id":16306755,"url":"https://github.com/oalders/is","last_synced_at":"2026-04-23T04:01:24.536Z","repository":{"id":164666292,"uuid":"640110628","full_name":"oalders/is","owner":"oalders","description":"an inspector for your environment","archived":false,"fork":false,"pushed_at":"2026-04-20T23:37:39.000Z","size":496,"stargazers_count":47,"open_issues_count":4,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-21T01:33:42.344Z","etag":null,"topics":["bash","cli","golang","shell","terminal"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oalders.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["oalders"]}},"created_at":"2023-05-13T03:05:15.000Z","updated_at":"2026-04-20T23:36:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"9ce0fe25-9ceb-4ba5-87f0-4fa63900b5ca","html_url":"https://github.com/oalders/is","commit_stats":null,"previous_names":["oalders/ndevr"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/oalders/is","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oalders%2Fis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oalders%2Fis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oalders%2Fis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oalders%2Fis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oalders","download_url":"https://codeload.github.com/oalders/is/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oalders%2Fis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32165201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T02:19:40.750Z","status":"ssl_error","status_checked_at":"2026-04-23T02:17:55.737Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","cli","golang","shell","terminal"],"created_at":"2024-10-10T21:11:32.481Z","updated_at":"2026-04-23T04:01:24.437Z","avatar_url":"https://github.com/oalders.png","language":"Go","funding_links":["https://github.com/sponsors/oalders"],"categories":[],"sub_categories":[],"readme":"# is: an inspector for your environment\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Introduction](#introduction)\n  * [Is the minimum version of this tool available?](#is-the-minimum-version-of-this-tool-available)\n  * [Is Neovim the Default Editor?](#is-neovim-the-default-editor)\n  * [Is this the target Operating System?](#is-this-the-target-operating-system)\n  * [Check the OS with a regex](#check-the-os-with-a-regex)\n  * [Is this a recent macOS?](#is-this-a-recent-macos)\n  * [Who am I?](#who-am-i)\n  * [Do we have go? Then install `goimports`](#do-we-have-go-then-install-goimports)\n  * [What's the version of bash?](#whats-the-version-of-bash)\n  * [What's the major version of zsh?](#whats-the-major-version-of-zsh)\n  * [Has gofumpt been modified in the last week?](#has-gofumpt-been-modified-in-the-last-week)\n  * [Has a file been modified in the last hour?](#has-a-file-been-modified-in-the-last-hour)\n  * [echo the OS name](#echo-the-os-name)\n  * [Get some debugging information about the OS](#get-some-debugging-information-about-the-os)\n  * [Pretty-Print Summaries in GitHub Actions](#pretty-print-summaries-in-github-actions)\n  * [Can user sudo without a password?](#can-user-sudo-without-a-password)\n* [Exit Codes are Everything](#exit-codes-are-everything)\n  * [Debugging error Codes](#debugging-error-codes)\n  * [Using a Regex](#using-a-regex)\n    * [Under the Hood](#under-the-hood)\n* [Top Level Commands](#top-level-commands)\n  * [audio](#audio)\n  * [arch](#arch)\n  * [battery](#battery)\n    * [state](#state)\n    * [current-charge](#current-charge)\n    * [count](#count)\n    * [charge-rate](#charge-rate)\n    * [current-capacity](#current-capacity)\n    * [design-capacity](#design-capacity)\n    * [design-voltage](#design-voltage)\n    * [last-full-capacity](#last-full-capacity)\n    * [voltage](#voltage)\n    * [--nth](#--nth)\n    * [--round](#--round)\n  * [cli](#cli)\n    * [age](#age)\n    * [version](#version)\n      * [version segments --major | --minor | --patch](#version-segments---major----minor----patch)\n    * [output](#output)\n      * [stdout](#stdout)\n      * [stderr](#stderr)\n      * [combined](#combined)\n      * [---arg (-a)](#---arg--a)\n      * [--compare](#--compare)\n    * [Tip: Using pipes](#tip-using-pipes)\n    * [Tip: Using Negative Numbers](#tip-using-negative-numbers)\n      * [--debug](#--debug)\n  * [fso](#fso)\n    * [age](#age-1)\n  * [os](#os)\n    * [version](#version-1)\n      * [version segments --major | --minor | --patch](#version-segments---major----minor----patch-1)\n    * [name](#name)\n      * [Equality](#equality)\n      * [Inequality](#inequality)\n      * [In a comma-delimited list](#in-a-comma-delimited-list)\n      * [Regex](#regex)\n      * [pretty-name](#pretty-name)\n      * [id](#id)\n      * [id-like](#id-like)\n      * [version-codename](#version-codename)\n  * [there](#there)\n    * [--verbose](#--verbose)\n    * [--all](#--all)\n    * [--json](#--json)\n  * [user](#user)\n    * [sudoer](#sudoer)\n  * [var](#var)\n    * [set](#set)\n    * [unset](#unset)\n    * [true](#true)\n    * [false](#false)\n      * [--compare](#--compare-1)\n  * [known](#known)\n  * [audio](#audio-1)\n    * [arch](#arch-1)\n    * [battery](#battery-1)\n    * [os](#os-1)\n      * [name](#name-1)\n      * [pretty-name](#pretty-name-1)\n      * [id](#id-1)\n      * [id-like](#id-like-1)\n      * [version](#version-2)\n      * [version-codename](#version-codename-1)\n    * [cli version](#cli-version)\n    * [var](#var-1)\n    * [summary](#summary)\n      * [battery](#battery-2)\n      * [os](#os-2)\n      * [var](#var-2)\n  * [install-completions](#install-completions)\n  * [--debug](#--debug-1)\n  * [--help](#--help)\n    * [subcommand --help](#subcommand---help)\n  * [--version](#--version)\n* [Installation](#installation)\n* [Bonus: Easier Version Parsing of Available Tools](#bonus-easier-version-parsing-of-available-tools)\n  * [Go (version)](#go-version)\n  * [Perl (--version)](#perl---version)\n  * [tmux (-V)](#tmux--v)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.png\" /\u003e\n\u003c/p\u003e\n\n## Introduction\n\n`is` is an inspector for your environment. I made it for my\n[dot-files](https://github.com/oalders/dot-files). `is` tries to make it just a\nlittle bit easier to run commands which rely on a specific OS or a specific CLI\nversion. Aside from the docs below, this [quick\nintroduction](https://www.olafalders.com/2023/09/28/is-an-inspector-for-your-environment/)\ncan get you up and running in a hurry.\n\n### Is the minimum version of this tool available?\n\n```bash\nis cli version tmux gt 3.2 \u0026\u0026 echo 🥳 || echo 😢\n```\n\n### Is Neovim the Default Editor?\n\n```bash\nis var EDITOR set \u0026\u0026 is var EDITOR eq nvim\n```\n\n### Is this the target Operating System?\n\n```bash\n(is os name eq darwin \u0026\u0026 echo 🍏 ) ||\n  (is os name eq linux \u0026\u0026 echo 🐧) ||\n  echo 💣\n```\n\n### Check the OS with a regex\n\n```bash\nis os name like \"da\\w{4}\" \u0026\u0026 echo 🍏\n```\n\n### Is this a recent macOS?\n\n```bash\nis os version-codename in ventura,monterey\n```\n\n### Who am I?\n\n```bash\nis cli output stdout whoami eq olaf\n```\n\n### Do we have go? Then install `goimports`\n\n```bash\nis there go \u0026\u0026 go install golang.org/x/tools/cmd/goimports@latest\n```\n\n### What's the version of bash?\n\n```text\n$ is known cli version bash\n5.2.15\n```\n\n### What's the major version of zsh?\n\n```text\n$ is known cli version --major zsh\n5\n```\n\n### Has gofumpt been modified in the last week?\n\n```text\nis cli age gofumpt lt 7 d\n```\n\n### Has a file been modified in the last hour?\n\n```text\nis fso age ./stats.txt lt 1 h\n```\n\n### echo the OS name\n\n```text\n$ echo \"i'm on $(is known os name) for sure\"\ni'm on darwin for sure\n```\n\n### Get some debugging information about the OS\n\nmacOS:\n\n```shell\n$ is known summary os\n┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓\n┃ Attribute        ┃ Value   ┃\n┣━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ name             ┃ darwin  ┃\n┣━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ version          ┃ 13.7.6  ┃\n┣━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ version-codename ┃ ventura ┃\n┗━━━━━━━━━━━━━━━━━━┻━━━━━━━━━┛\n```\n\n```shell\nis known summary os --json\n```\n\n```json\n{\n    \"name\": \"darwin\",\n    \"version\": \"15.4.1\",\n    \"version-codename\": \"sequoia\"\n}\n```\n\n```shell\nis known summary os --md\n```\n\n\n| Attribute | Value |\n|---|---|\n| name | linux |\n| version | 3.22.0 |\n| id | alpine |\n| pretty-name | Alpine Linux v3.22 |\n\n\n### Pretty-Print Summaries in GitHub Actions\n\nAfter you have `is` installed, you can echo markdown tables to the\n`$GITHUB_STEP_SUMMARY` environment variable. This will give you a readable\ntables that live outside of the log files.\n\n```yaml\njobs:\n  linux:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Install ubi\n        uses: oalders/install-ubi-action@v0.0.2\n\n      - name: Install \"is\"\n        run: sudo ubi --project oalders/is --in /usr/local/bin\n\n      - name: Display summaries\n        run: |\n          is known summary os  --md \u003e\u003e $GITHUB_STEP_SUMMARY\n          is known summary var --md \u003e\u003e $GITHUB_STEP_SUMMARY\n\n```\n\n### Can user sudo without a password?\n\n```bash\nis user sudoer || echo 😭\n```\n\n## Exit Codes are Everything\n\n`is` returns an exit code of `0` on success and non-zero (usually `1`) on\nfailure. We can leverage this in shell scripting:\n\nIn a script:\n\n```bash\n#!/bin/bash\n\nif is os name eq darwin; then\n  # This is a Mac. Creating karabiner config dir.\"\n  mkdir -p \"$HOME/.config/karabiner\"\nfi\n```\n\nAt the command line:\n\n```bash\nis os name ne darwin \u0026\u0026 echo \"this is not a mac\"\n```\n\n### Debugging error Codes\n\nIn `bash` and `zsh` (and possibly other shells), `$?` contains the value of the\nlast command's exit code.\n\n```text\n$ is os name eq x\n$ echo $?\n1\n$ is os name eq darwin\n0\n```\n\n### Using a Regex\n\nThe `like` and `unlike` operators accept a regular expression. We may need to\nquote our regex. For instance:\n\n```bash\nis os name like darw\\w\n```\n\nshould be\n\n```bash\nis os name like \"darw\\w\"\n```\n\nWe can the debug flag to see how our regex may have been changed by our shell:\n\n```text\n$ is os name like darw\\w --debug\ncomparing regex \"darww\" with darwin\n```\n\nIn this case we can see that the unquoted `\\w` is turned into `w` by the shell\nbecause it was not quoted.\n\nWe can also use regexes with no special characters at all:\n\n```bash\nis os version-codename unlike ventura\n```\n\n#### Under the Hood\n\n🚨 Leaky abstraction alert!\n\nRegex patterns are passed directly to Golang's `regexp.MatchString`. We can\ntake advantage of this when crafting regexes. For instance, for a case\ninsensitive search:\n\n```text\nis cli output stdout date like \"(?i)wed\"\n```\n\n## Top Level Commands\n\n### audio\n\nChecks against known audio attributes, if available. Returns non-zero and\nprints an error message if audio cannot be discovered.\n\nAvailable attributes:\n\n* level\n* muted\n\n`level` is a value from 0 to 100.\n\n```shell\nis audio level gte 56 \u0026\u0026 echo \"loud enough\"\n```\n\n```shell\nis audio muted \u0026\u0026 echo \"nothing to hear here\"\n```\n\n### arch\n\nChecks against the arch which this binary has been compiled for.\n\n```text\nis arch eq amd64\n```\n\n```text\nis arch like 64\n```\n\nSupported comparisons are:\n\n- `eq`\n- `ne`\n- `in`\n- `like`\n- `unlike`\n\nWe can try `is known arch` to get the value for our installed binary or run this\ncommand with the `--debug` flag.\n\nTheoretical possibilities are:\n\n```text\n386\namd64\narm\narm64\nloong64\nmips\nmips64\nmips64le\nmipsle\nppc64\nppc64le\nriscv64\ns390x\nwasm\n```\n\nhowever, there are available binaries for only some of these values.\n\n### battery\n\n```shell\n./is battery --help\nUsage: is battery \u003cattribute\u003e \u003cop\u003e \u003cval\u003e\n\nCheck battery attributes. e.g. \"is battery state eq charging\"\n\nArguments:\n  \u003cattribute\u003e    [charge-rate|count|current-capacity|current-charge|design-capacity|design-voltage|last-full-capacity|state|voltage]\n  \u003cop\u003e           [eq|ne|gt|gte|in|like|lt|lte|unlike]\n  \u003cval\u003e\n\nFlags:\n  -h, --help       Show context-sensitive help.\n      --debug      turn on debugging statements\n      --version    Print version to screen\n\n      --nth=1      Specify which battery to use (1 for the first battery)\n      --round      Round float values to the nearest integer\n```\n\nCompare against battery attributes for power management. This is useful for writing scripts that depend on battery state or charge level.\n\n```bash\nis battery state eq charging\n```\n\n```bash\nis battery current-charge lt 20 \u0026\u0026 notify-send \"Battery Low\" \"Battery level below 20%\"\n```\n\n#### state\n\nCheck the current state of the battery:\n\n```bash\nis battery state eq charging\n```\n\n```bash\nis battery state in charging,full\n```\n\n```bash\nis battery state like discharg\n```\n\nPossible states include:\n\n- charging\n- discharging\n- idle\n- empty\n- full\n- unknown\n- undefined\n\n#### current-charge\n\nCheck the current charge percentage of the battery:\n\n```bash\nis battery current-charge lt 15 \u0026\u0026 echo \"Battery critically low!\"\n```\n\n#### count\n\nCheck the number of batteries detected in the system:\n\n```bash\nis battery count gt 0 || echo \"No battery found\"\n```\n\n#### charge-rate\n\nThis is the current (momentary) charge rate (in mW). It is always non-negative, check `is battery state` to see whether it means charging or discharging.\n\nSee \u003chttps://github.com/distatus/battery/blob/master/battery.go\u003e\n\n#### current-capacity\n\nCheck the current (momentary) capacity in mWh:\n\n```bash\nis battery current-capacity gt 7000\n```\n\n#### design-capacity\n\nCheck the design capacity in mWh:\n\n```bash\nis battery design-capacity gt 7000\n```\n\n#### design-voltage\n\nCheck the design voltage in mWh:\n\n```bash\nis battery design-voltage gt 13\n```\n\n#### last-full-capacity\n\nCheck the capacity at last full charge in mWh:\n\n```bash\nis battery last-full-capacity gt 7000\n```\n\n#### voltage\n\nCheck the current battery voltage in V:\n\n```bash\nis battery voltage gt 10\n```\n\n#### --nth\n\nSpecify which battery to check if multiple batteries are present:\n\n```bash\nis battery --nth=2 state eq charging\n```\n\n#### --round\n\nRound float values to the nearest integer:\n\n```bash\nis battery --round current-charge eq 85\n```\n\nWithout `--round`:\n\n```bash\nis battery current-charge eq 85.4\n```\n\nSupported comparisons are:\n\n- `lt`\n- `lte`\n- `eq`\n- `gte`\n- `gt`\n- `in`\n- `ne`\n- `like`\n- `unlike`\n\n### cli\n\n#### age\n\nCompare against the last modified date of a command's file.\n\n```bash\nis cli age tmux lt 18 hours\n```\n\nDon't let `goimports` get more than a week out of date.\n\n```bash\nis cli age goimports gt 7 days \u0026\u0026 go install golang.org/x/tools/cmd/goimports@latest\n```\n\nUpdate `shfmt` basically daily, but only if `go` is installed.\n\n```bash\nif is there go; then\n    if is cli age shfmt gt 18 hours; then\n        go install mvdan.cc/sh/v3/cmd/shfmt@latest\n    fi\nelse\n    echo \"Go not found. Not installing shfmt\"\nfi\n```\n\nSupported comparisons are:\n\n- `lt`\n- `gt`\n\nSupported units are:\n\n- `s`\n- `second`\n- `seconds`\n- `m`\n- `minute`\n- `minutes`\n- `h`\n- `hour`\n- `hours`\n- `d`\n- `day`\n- `days`\n\nNote that `d|day|days` is shorthand for 24 hours. DST offsets are not taken\ninto account here.\n\nThe `--debug` flag can give us some helpful information when troubleshooting\ndate math.\n\n#### version\n\nCompare versions of available commands. Returns exit code of 0 if condition is\ntrue and exit code of 1 if condition is false.\n\n```bash\nis cli version go gte 1.20.4 || bash upgrade-go.sh\n```\n\n##### version segments --major | --minor | --patch\n\nIf we want to match only on part of a version, we can do that by specifying\nwhich segment of the version we want to match on, where the pattern is\n`major.minor.patch`. Given a version number of `1.2.3` that would make 1 the\n`major` version, 2 the `minor` version and `3` the patch version. If the\nversion number does not include a `patch`, then it is assumed to be zero.\nLikewise for a missing `minor` segment.\n\nThe segment flags are `--major`, `--minor` and `--patch`. They are mutually\nexclusive, only one of these flags can be passed per command.\n\nLet's rework the example above to say that any version of `go` with a minor\nversion \u003e= 20 means we don't need to upgrade.\n\n```bash\nis cli version --minor go gte 20 || bash upgrade-go.sh\n```\n\nWe could also express this in the following way, if we want to match on the\nmajor version as well.\n\n```bash\nis cli version go gte 1.20\n```\n\nSupported comparisons are:\n\n- `lt`\n- `lte`\n- `eq`\n- `gte`\n- `gt`\n- `in`\n- `ne`\n- `like`\n- `unlike`\n\n#### output\n\nRun an arbitrary command and compare the output of `stdout`, `stderr` or\n`combined`. Whitespace is automatically trimmed from the left and right of\noutput before any comparisons are attempted. So, we don't need to worry about\ntrimming output with leading spaces like this:\n\n```text\ncat README.md | wc -l\n     847\n```\n\nThe format for this command is:\n\n```text\nis cli output              \\\n  [stdout|stderr|combined] \\\n  some-command             \\\n  --arg foo --arg bar      \\\n  [lt|lte|eq|gte|ne|like|unlike] \"string/regex to match\"\n```\n\n##### stdout\n\n```bash\nis cli output stdout date like Wed\n```\n\nCase insensitive:\n\n```bash\nis cli output stdout date like \"(?i)wed\"\n```\n\n##### stderr\n\n`ssh` prints its version to `stderr`.\n\n```text\nis cli output stderr ssh --arg=\"-V\" like 9.0p1\n```\n\n##### combined\n\n`combined` allows us to match on `stdout` and `stderr` at the same time.\n\n```text\nis cli output combined ssh --arg=\"-V\" like 9.0p1\n```\n\n##### ---arg (-a)\n\nOptional argument to command. Can be used more than once.\n\nLet's match on the results of `uname -m -n`.\n\n```bash\nis cli output stdout uname --arg=\"-m\" --arg=\"-n\" eq \"olafs-mbp-2.lan x86_64\"\n```\n\nIf our args don't contain special characters or spaces, we may not need to\nquote them. Let's match on the results of `cat README.md`.\n\n```bash\nis cli output stdout cat --arg README.md like \"an inspector for your environment\"\n```\n\n##### --compare\n\nOptional argument to command. Defaults to `optimistic`. Because comparisons\nlike `eq` mean different things when comparing strings, integers and floats, we\ncan tell `is` what sort of a comparison to perform. Our options are:\n\n- float\n- integer\n- string\n- version\n- optimistic\n\n`optimistic` will first try a `string` comparison. If this fails, it will try a\n`version` comparison. This will \"Do What I Mean\" in a lot of cases, but if we\nwant to constrain the check to a specific type, we can certainly do that.\n\n```text\nis cli output stdout                            \\\n  bash --arg=\"-c\" --arg=\"cat README.md | wc -l\" \\\n  gt 10                                         \\\n  --debug --compare integer\n```\n\n#### Tip: Using pipes\n\nTo pipe output from one command to another, we'll need to do something that is\nequivalent to: `bash -c \"some-command | other-command\"`\n\nTo count the number of lines returned by `date`, we might normally write:\n\n```text\n$ date | wc -l\n       1\n```\n\nVia `bash -c`:\n\n```text\n$ bash -c \"date | wc -l\"\n       1\n```\n\nNow, run via `is` and assert that there really is just one line:\n\n```text\nis cli output stdout bash --arg='-c' --arg=\"date|wc -l\" eq 1\n```\n\nLet's make this more succinct. We can make this a little shorter, because `is`\nhandles `bash -c` as a special case:\n\n```text\nis cli output stdout \"bash -c\" -a \"date|wc -l\" eq 1\n```\n\n#### Tip: Using Negative Numbers\n\nPassing negative integers as expected values is a bit tricky, since we don't\nwant them to be interpreted as flags.\n\n```bash\n$ is cli output stdout 'bash -c' -a 'date|wc -l' gt -1\n```\n\n\u003e 💥 is: error: unknown flag -1, did you mean one of \"-h\", \"-a\"?\n\nWe can use `--` before the expected value to get around this. 😅\n\n```bash\n$ is cli output stdout 'bash -c' -a 'date|wc -l' gt -- -1\n```\n\n##### --debug\n\nUse the `--debug` flag to see where comparisons are failing:\n\n```text\nis cli output stdout uname --arg=\"-m\" --arg=\"-n\" eq \"olafs-mbp-2.lan x86_65\" --debug\n2023/09/13 23:05:26 comparison \"olafs-mbp-2.lan x86_64\" eq \"olafs-mbp-2.lan x86_65\"\n2023/09/13 23:05:26 comparison failed: olafs-mbp-2.lan x86_64 eq olafs-mbp-2.lan x86_65\n```\n\nSupported comparisons are:\n\n- `lt`\n- `lte`\n- `eq`\n- `gte`\n- `gt`\n- `in`\n- `ne`\n- `like`\n- `unlike`\n\n👉 Nota bene: because `is` doesn't know what you're trying to match, it will,\nin some cases try to do an optimistic comparison. That is, it will try a string\ncomparison first and then a numeric comparison. Hopefully this will \"do the\nright thing\" for you. If not, please open an issue.\n\n### fso\n\n`fso` is short for filesystem object (file, directory, link, etc). This command\nis very similar to `cli age`. The difference between `cli age` and `fso age` is\nthat `fso` will not search your `$PATH`. You may provide either a relative or\nan absolute path.\n\n#### age\n\nCompare against the last modified date of a file.\n\n```bash\nis fso age /tmp/programs.csv lt 18 hours\n```\n\nCompare against the last modified date of a directory.\n\n```bash\nis fso age ~./local/cache gt 1 d\n```\n\nSupported comparisons are:\n\n- `lt`\n- `gt`\n\nSupported units are:\n\n- `s`\n- `second`\n- `seconds`\n- `m`\n- `minute`\n- `minutes`\n- `h`\n- `hour`\n- `hours`\n- `d`\n- `day`\n- `days`\n\nNote that `d|day|days` is shorthand for 24 hours. DST offsets are not taken\ninto account here.\n\nThe `--debug` flag can give us some helpful information when troubleshooting\ndate math.\n\n### os\n\nInformation specific to the current operating system\n\n#### version\n\n```bash\nis os version gt 22\n```\n\n```bash\nis os version like \"13.4.\\d\"\n```\n\n##### version segments --major | --minor | --patch\n\nIf we want to match only on part of a version, we can do that by specifying\nwhich segment of the version we want to match on, where the pattern is\n`major.minor.patch`. Given a version number of `1.2.3` that would make 1 the\n`major` version, 2 the `minor` version and `3` the patch version. If the\nversion number does not include a `patch`, then it is assumed to be zero.\nLikewise for a missing `minor` segment.\n\nThe segment flags are `--major`, `--minor` and `--patch`. They are mutually\nexclusive, only one of these flags can be passed per command.\n\n```text\nis os version --major eq 13\n```\n\nSupported comparisons are:\n\n- `lt`\n- `lte`\n- `eq`\n- `gte`\n- `gt`\n- `in`\n- `ne`\n- `like`\n- `unlike`\n\n#### name\n\nUnder the hood, this returns the value of `runtime.GOOS`, a constant which is\nset at compile time. So, `is` reports on on the OS name which is the target of\nbuild rather than running `uname` or something like that. This is \"good enough\"\nfor my purposes. If it's not good enough for yours, we probably need to add\nmore build targets.\n\nAvailable comparisons are:\n\n- `eq`\n- `ne`\n- `in`\n- `like`\n- `unlike`\n\n##### Equality\n\n```bash\nis os name eq darwin\n```\n\n##### Inequality\n\n```bash\nis os name ne linux\n```\n\n##### In a comma-delimited list\n\n```bash\nis os name in darwin,linux\n```\n\n##### Regex\n\n```bash\nis os name like darw\n```\n\n```bash\nis os name like \"dar\\w{3}\"\n```\n\n```bash\nis os name unlike \"foo\\d\"\n```\n\nPossible values for `name`:\n\n```text\ndarwin\nlinux\n```\n\n##### pretty-name\n\nLinux only.\n\n```bash\nis os pretty-name eq \"Ubuntu 22.04.2 LTS\"\n```\n\nAvailable comparisons are:\n\n- `eq`\n- `ne`\n- `in`\n- `like`\n- `unlike`\n\n##### id\n\nLinux only.\n\n```bash\nis os id eq ubuntu\n```\n\nAvailable comparisons are:\n\n- `eq`\n- `ne`\n- `in`\n- `like`\n- `unlike`\n\n##### id-like\n\n```bash\nis os id-like eq debian\n```\n\nAvailable comparisons are:\n\n- `eq`\n- `ne`\n- `in`\n- `like`\n- `unlike``\n\n##### version-codename\n\n```bash\nis os version-codename eq jammy\n```\n\nAvailable comparisons are:\n\n- `eq`\n- `ne`\n- `in`\n- `like`\n- `unlike`\n\nOn Linux, the value for `version-codename` is taken from `/etc/os-release`. For\nMacs, the values are mapped inside this application.\n\nPossible values for Mac:\n\n- ventura\n- monterey\n- big sur\n- catalina\n- mojave\n- high sierra\n- sierra\n- el capitan\n- yosemite\n- mavericks\n- mountain lion\n\n### there\n\nReturns exit code of 0 if command exists and exit code of 1 if command cannot\nbe found.\n\n```bash\nis there tmux \u0026\u0026 echo \"we have tmux\"\n```\n\n#### --verbose\n\n`--verbose` is only useful without the `--all` or `--json` flags, since they\nimply `--verbose`. Using this flag you can see the path and version of the\nfirst binary which is in your `$PATH`.\n\n\n```shell\nis there bash --verbose\n┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓\n┃ Path                ┃ Version ┃\n┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ /usr/local/bin/bash ┃ 5.2.37  ┃\n┗━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━┛\n```\n\n#### --all\n\nThe all switch adds command output, which is an ASCII table of all of\nthe binaries which have been found, as well as their versions. This is\nessentially a wrapper around `which -a`, with added version parsing.\n\n```shell\n$ is there bash --all\n┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓\n┃ Path                ┃ Version ┃\n┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ /usr/local/bin/bash ┃ 5.2.37  ┃\n┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ /bin/bash           ┃ 3.2.57  ┃\n┗━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━┛\n```\n\n#### --json\n\n```shell\nis there bash --json\n```\n\n```json\n[\n    {\n        \"path\": \"/opt/homebrew/bin/bash\",\n        \"version\": \"5.2.37\"\n    }\n]\n```\n\n```shell\nis there bash --all --json\n```\n\n```json\n[\n    {\n        \"path\": \"/opt/homebrew/bin/bash\",\n        \"version\": \"5.2.37\"\n    },\n    {\n        \"path\": \"/bin/bash\",\n        \"version\": \"3.2.57\"\n    }\n]\n```\n\n### user\n\n#### sudoer\n\n```bash\nis user sudoer \u0026\u0026 sudo apt-get install ripgrep\n```\n\nReturns 1 if the current appears to be able to `sudo` without being prompted\nfor a password.\n\nThis is useful for scripts where we want to install via `sudo`, but we don't\nwant the script to be interactive. That means we can skip installing things\nthat require `sudo` and handle them in some other place.\n\n### var\n\nCheck if environment variables are set, unset or contain a specific value.\n\n```bash\nis var EDITOR set \u0026\u0026 is var EDITOR like vim\n\nis var EDITOR set \u0026\u0026 is var EDITOR eq \"\"\n```\n\n`is var` can only operate on environment variables which are available in its\nenvironment. This means that you may need to export some variables before you\ncan invoke `is var`. For example, if you have created a variable in the current\nscript, it should be exported before `is var` is used.\n\n```shell\nSLOW_HORSE=rivercartwright\nexport SLOW_HORSE\nis var SLOW_HORSE like cart \u0026\u0026 echo \"blue shirt, white tee\"\n```\n\n#### set\n\n```bash\nis var EDITOR set\n```\n\n#### unset\n\n```bash\nunset EDITOR\nis var EDITOR unset\n```\n\n#### true\n\nCheck if an environment variable's value can be parsed as a boolean `true`. Uses Go's `strconv.ParseBool` function, which accepts: `1`, `t`, `T`, `TRUE`, `true`, `True` as true values.\n\n```bash\nexport DEBUG=true\nis var DEBUG true \u0026\u0026 echo \"Debug mode is enabled\"\n```\n\n```bash\nexport VERBOSE=1\nis var VERBOSE true \u0026\u0026 echo \"Verbose output enabled\"\n```\n\n#### false\n\nCheck if an environment variable's value can be parsed as a boolean `false`. Uses Go's `strconv.ParseBool` function, which accepts: `0`, `f`, `F`, `FALSE`, `false`, `False` as false values.\n\n```bash\nexport PRODUCTION=false\nis var PRODUCTION false \u0026\u0026 echo \"Not in production mode\"\n```\n\n```bash\nexport DEBUG=0\nis var DEBUG false \u0026\u0026 echo \"Debug mode is disabled\"\n```\n\n`set`, `unset`, `true`, and `false` don't require additional arguments, but the comparison operators do.\n\nSupported operations are:\n\n- `set` - check if variable is set\n- `unset` - check if variable is unset\n- `true` - check if variable value is a boolean true\n- `false` - check if variable value is a boolean false\n- `lt` - less than comparison\n- `lte` - less than or equal comparison\n- `eq` - equality comparison\n- `gte` - greater than or equal comparison\n- `gt` - greater than comparison\n- `in` - check if value is in comma-separated list\n- `ne` - not equal comparison\n- `like` - regex match\n- `unlike` - inverse regex match\n\nBoth `eq` and `ne` allow for comparisons with an empty string:\n\n```shell\nSET_BUT_EMPTY=\nexport SET_BUT_EMPTY\n\nis var SET_BUT_EMPTY set \u0026\u0026 is var SET_BUT_EMPTY eq \"\"\n\nNOT_EMPTY=lebowski\nexport NOT_EMPTY\n\nis var NOT_EMPTY set \u0026\u0026 is var NOT_EMPTY ne \"\"\n```\n\n##### --compare\n\nOptional argument to command. Defaults to `optimistic`. Because comparisons\nlike `eq` mean different things when comparing strings, integers and floats, we\ncan tell `is` what sort of a comparison to perform. Our options are:\n\n- float\n- integer\n- string\n- version\n- optimistic\n\n`optimistic` will first try a `string` comparison. If this fails, it will try a\n`version` comparison. This will \"Do What I Mean\" in a lot of cases, but if we\nwant to constrain the check to a specific type, we can certainly do that.\n\n💥 alert:\n\n```bash\nFLOATER=1.1 is var FLOATER eq 1.1 --compare integer\n```\n\n```text\nis: error: wanted result must be an integer\n```\n\n### known\n\nPrints known information about a resource to `STDOUT`. Returns `0` on success\nand `1` if info cannot be found.\n\n### audio\n\nPrints value of some audio attributes, if available. Returns non-zero  and\nprints an error message if audio cannot be discovered.\n\nAvailable attributes:\n\n- level\n- muted\n\n`level` prints a value from 0 to 100.\n\n```shell\n$ is known audio level\n56\n```\n\n`muted` prints a string of `true` or `false`\n\n```shell\n$ is known audio muted\nfalse\n```\n\n#### arch\n\nPrints the value of golang's `runtime.GOARCH`. Note that this is the arch that\nthe binary was compiled for. It's not running `uname` under the hood.\n\nTheoretical possibilities are:\n\n```text\n386\namd64\narm\narm64\nloong64\nmips\nmips64\nmips64le\nmipsle\nppc64\nppc64le\nriscv64\ns390x\nwasm\n```\n\nhowever, there are available binaries for only some of these values.\n\n#### battery\n\nGet information about the system battery without performing a check.\n\n```text\n$ is known battery state\ncharging\n```\n\n```text\n$ is known battery current-charge\n85.4\n```\n\nYou can specify which battery to query with `--nth`:\n\n```text\n$ is known battery --nth=2 state\ndischarging\n```\n\nRound float values to the nearest integer:\n\n```text\n$ is known battery --round current-charge\n85\n```\n\nAvailable attributes:\n\n* state (one of)\n\t* \tundefined\n\t*  unknown\n\t*  empty\n\t*  full\n\t*  charging\n\t*  discharging\n\t*  idle\n* current-charge (mWh)\n* count (int)\n* charge-rate (V)\n* current-capacity (mWh)\n* design-capacity (mWh)\n* design-voltage (V)\n* last-full-capacity (mWh)\n* voltage (V)\n\n#### os\n\nDetails specific to the current operating system.\n\n##### name\n\nUnder the hood, this returns the value of `runtime.GOOS`, a constant which is\nset at compile time. So, `is` reports on on the OS name which is the target of\nbuild rather than running `uname` or something like that. This is \"good enough\"\nfor my purposes. If it's not good enough for yours, we probably need to add\nmore build targets.\n\n```text\n$ is known os name\nlinux\n```\n\nPossible values for `name`:\n\n```text\ndarwin\nlinux\n```\n\n##### pretty-name\n\nLinux only.\n\n```text\n$ is known os pretty-name\nUbuntu 22.04.2 LTS\n```\n\n##### id\n\nLinux only.\n\n```text\n$ is known os id\nubuntu\n```\n\n##### id-like\n\nLinux only.\n\n```text\n$ is known os id-like\ndebian\n```\n\n##### version\n\n```text\n$ is known os version\n22.04\n```\n\n```text\n$ is known os version --major\n22\n```\n\n```text\n$ is known os version --minor\n04\n```\n\n```text\n$ is known os version --patch\n0\n```\n\nPlease see the docs on `os version` for more information on `--major`,\n`--minor` and `--patch`.\n\n##### version-codename\n\n```text\n$ is known os version-codename\njammy\n```\n\n#### cli version\n\n```text\n$ is known cli version tmux\n2.7\n```\n\n```text\n$ is known cli version --major tmux\n2\n```\n\n```text\n$ is known cli version --minor tmux\n7\n```\n\n```text\n$ is known cli version --patch tmux\n0\n```\n\nPlease see the docs on `os version` for more information on `--major`,\n`--minor` and `--patch`.\n\n#### var\n\n```shell\n$ is known var PATH\n/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\n```\n\nThis is not so useful on its own, but combined with `--json` it can give you a readable `$PATH`.\n\n```\n$ is known var PATH --json\n[\n    \"/go/bin\",\n    \"/usr/local/go/bin\",\n    \"/usr/local/sbin\",\n    \"/usr/local/bin\",\n    \"/usr/sbin\",\n    \"/usr/bin\",\n    \"/sbin\",\n    \"/bin\"\n]\n```\n\nNow we can do something like `is known var PATH --json | jq .[1]` to get the\nsecond item in the list.\n\n#### summary\n\n`summary` is a special subcommand, which aggregates known data for another\nsubcommand and emits it to `STDOUT` as `json`. This replaces the previous\nbehaviour of `--debug` for `is known battery` and `is known os`.\n\n##### battery\n\n`is known summary battery`\n\n```json\n{\n    \"state\": \"discharging\",\n    \"battery-number\": 1,\n    \"count\": 1,\n    \"charge-rate\": 5700.2,\n    \"current-capacity\": 69231.52,\n    \"current-charge\": 91,\n    \"design-capacity\": 74620.8,\n    \"design-voltage\": 12.955,\n    \"last-full-capacity\": 75942.21,\n    \"voltage\": 12.955\n}\n```\n\n##### os\n\n```shell\n$ is known summary os\n┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓\n┃ Attribute   ┃ Value              ┃\n┣━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━┫\n┃ name        ┃ linux              ┃\n┣━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━┫\n┃ version     ┃ 3.22.0             ┃\n┣━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━┫\n┃ id          ┃ alpine             ┃\n┣━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━┫\n┃ pretty-name ┃ Alpine Linux v3.22 ┃\n┗━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━┛\n```\n\n```shell\n$ is known summary os\n┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓\n┃ Attribute        ┃ Value   ┃\n┣━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ name             ┃ darwin  ┃\n┣━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ version          ┃ 13.7.6  ┃\n┣━━━━━━━━━━━━━━━━━━╋━━━━━━━━━┫\n┃ version-codename ┃ ventura ┃\n┗━━━━━━━━━━━━━━━━━━┻━━━━━━━━━┛\n```\n\n`is known summary os --json`\n\n```json\n{\n    \"id\": \"alpine\",\n    \"name\": \"linux\",\n    \"pretty-name\": \"Alpine Linux v3.22\",\n    \"version\": \"3.22.0\"\n}\n```\n\n##### var\n\n```shell\nis known summary var\n```\n\nThis will emit your environment variables in a tabular layout. It will split\n`PATH` and `MANPATH` on newlines, to make them easier to read.\n\n```shell\n┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n┃ Name           ┃ Value             ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ GOLANG_VERSION ┃ 1.24.4            ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ GOPATH         ┃ /go               ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ GOTOOLCHAIN    ┃ local             ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ HOME           ┃ /root             ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ HOSTNAME       ┃ bb7d32c277e9      ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ PATH           ┃ /go/bin           ┃\n┃                ┃ /usr/local/go/bin ┃\n┃                ┃ /usr/local/sbin   ┃\n┃                ┃ /usr/local/bin    ┃\n┃                ┃ /usr/sbin         ┃\n┃                ┃ /usr/bin          ┃\n┃                ┃ /sbin             ┃\n┃                ┃ /bin              ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ PWD            ┃ /workspace        ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ SHLVL          ┃ 1                 ┃\n┣━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n┃ TERM           ┃ xterm             ┃\n┗━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━┛\n```\n\n```shell\nis known summary var --json\n```\n\n```json\n{\n    \"GOLANG_VERSION\": \"1.24.4\",\n    \"GOPATH\": \"/go\",\n    \"GOTOOLCHAIN\": \"local\",\n    \"HOME\": \"/root\",\n    \"HOSTNAME\": \"bb7d32c277e9\",\n    \"PATH\": [\n        \"/go/bin\",\n        \"/usr/local/go/bin\",\n        \"/usr/local/sbin\",\n        \"/usr/local/bin\",\n        \"/usr/sbin\",\n        \"/usr/bin\",\n        \"/sbin\",\n        \"/bin\"\n    ],\n    \"PWD\": \"/workspace\",\n    \"SHLVL\": \"1\",\n    \"TERM\": \"xterm\"\n}\n```\n\n```shell\nis known summary var --md\n```\n\n\n| Name | Value |\n|---|---|\n| GOLANG_VERSION | 1.24.4 |\n| GOPATH | /go |\n| GOTOOLCHAIN | local |\n| HOME | /root |\n| HOSTNAME | 44db2d2f4c32 |\n| PATH | /go/bin\u003cbr\u003e/usr/local/go/bin\u003cbr\u003e/usr/local/sbin\u003cbr\u003e/usr/local/bin\u003cbr\u003e/usr/sbin\u003cbr\u003e/usr/bin\u003cbr\u003e/sbin\u003cbr\u003e/bin |\n| PWD | /workspace |\n| SHLVL | 1 |\n| TERM | xterm |\n\n\n### install-completions\n\nThis is a two step process. First, run\n\n```bash\nis install-completions\n```\n\nThen run the command which is printed to your terminal in order to get\ncompletion in your current session.\n\n```bash\n$ is install-completions\ncomplete -C /Users/olaf/local/bin/is is\n```\n\nOr add the command to a `.bashrc` or similar in order to get completion across\nall sessions.\n\n### --debug\n\nPrint some debugging information to `STDOUT`.\n\n```text\n$ is os name eq darwins --debug\nComparison failed: darwin eq darwins\n```\n\n### --help\n\nTop level command help.\n\n```text\nUsage: is \u003ccommand\u003e\n\nan inspector for your environment\n\nFlags:\n  -h, --help       Show context-sensitive help.\n      --debug      turn on debugging statements\n      --version    Print version to screen\n\nCommands:\n  arch \u003cop\u003e \u003cval\u003e\n    Check arch e.g. \"is arch like x64\"\n\n  cli version \u003cname\u003e \u003cop\u003e \u003cval\u003e\n    Check version of command. e.g. \"is cli version tmux gte 3\"\n\n  cli age \u003cname\u003e \u003cop\u003e \u003cval\u003e \u003cunit\u003e\n    Check last modified time of cli (2h, 4d). e.g. \"is cli age tmux gt 1 d\"\n\n  cli output \u003cstream\u003e \u003ccommand\u003e \u003cop\u003e \u003cval\u003e\n    Check output of a command. e.g. \"is cli output stdout \"uname -a\" like\n    \"Kernel Version 22.5\"\n\n  fso age \u003cname\u003e \u003cop\u003e \u003cval\u003e \u003cunit\u003e\n    Check age (last modified time) of an fso (2h, 4d). e.g. \"is fso age\n    /tmp/log.txt gt 1 d\"\n\n  known arch [\u003cattr\u003e]\n    Print arch without check. e.g. \"is known arch\"\n\n  known os \u003cattribute\u003e\n    Print without check. e.g. \"is known os name\"\n\n  known cli \u003cattribute\u003e \u003cname\u003e\n    Print without check. e.g. \"is known cli version git\"\n\n  os \u003cattribute\u003e \u003cop\u003e \u003cval\u003e\n    Check OS attributes. e.g. \"is os name eq darwin\"\n\n  there \u003cname\u003e\n    Check if command exists. e.g. \"is there git\"\n\n  user [\u003csudoer\u003e]\n    Info about current user. e.g. \"is user sudoer\"\n\n  var \u003cname\u003e \u003cop\u003e [\u003cval\u003e]\n    Check environment variables. e.g. \"is var EDITOR eq nvim\"\n\n  install-completions\n    install shell completions. e.g. \"is install-completions\" and then run the\n    command which is printed to your terminal to get completion in your current\n    session. add the command to a .bashrc or similar to get completion across\n    all sessions.\n\nRun \"is \u003ccommand\u003e --help\" for more information on a command.\n```\n\n#### subcommand --help\n\n```text\nUsage: is os \u003cattribute\u003e \u003cop\u003e \u003cval\u003e\n\nCheck OS attributes. e.g. \"is os name eq darwin\"\n\nArguments:\n  \u003cattribute\u003e    [id|id-like|pretty-name|name|version|version-codename]\n  \u003cop\u003e           [eq|ne|gt|gte|in|like|lt|lte|unlike]\n  \u003cval\u003e\n\nFlags:\n  -h, --help       Show context-sensitive help.\n      --debug      turn on debugging statements\n      --version    Print version to screen\n\n      --major      Only match on the major OS version (e.g. major.minor.patch)\n      --minor      Only match on the minor OS version (e.g. major.minor.patch)\n      --patch      Only match on the patch OS version (e.g. major.minor.patch)\n```\n\n### --version\n\nPrint current version of `is`\n\n```bash\nis --version\n```\n\n## Installation\n\nChoose from the following options to install `is`.\n\n1. [Download a release](https://github.com/oalders/is/releases)\n1. Use `go install`\n  * `go install github.com/oalders/is@latest`\n  * `go install github.com/oalders/is@v0.13.0`\n1. Use [ubi](https://github.com/houseabsolute/ubi)\n\n```bash\n#!/usr/bin/env bash\n\nset -e -u -x -o pipefail\n\n# Or choose a different dir in your $PATH\ndir=\"$HOME/local/bin\"\n\nif [ ! \"$(command -v ubi)\" ]; then\n    curl --silent --location \\\n        https://raw.githubusercontent.com/houseabsolute/ubi/master/bootstrap/bootstrap-ubi.sh |\n        TARGET=$dir sh\nfi\n\nubi --project oalders/is --in \"$dir\"\n```\n\n## Bonus: Easier Version Parsing of Available Tools\n\nForget about the remembering the different `version` incantations of command\nline tools. Don't make up regexes to extract the actual version number.\n\n### Go (version)\n\n```text\n$ go version\ngo version go1.20.4 darwin/amd64\n```\n\n```text\n$ is known cli version go\n1.20.4\n```\n\n### Perl (--version)\n\n```text\n$ perl --version\n\nThis is perl 5, version 36, subversion 1 (v5.36.1) built for darwin-2level\n\nCopyright 1987-2023, Larry Wall\n\nPerl may be copied only under the terms of either the Artistic License or the\nGNU General Public License, which may be found in the Perl 5 source kit.\n\nComplete documentation for Perl, including FAQ lists, should be found on\nthis system using \"man perl\" or \"perldoc perl\".  If you have access to the\nInternet, point your browser at https://www.perl.org/, the Perl Home Page.\n```\n\n```text\n$ is known cli version perl\nv5.36.1\n```\n\n### tmux (-V)\n\n```text\n$ tmux -V\ntmux 3.3a\n```\n\n```text\n$ is known cli version tmux\n3.3a\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foalders%2Fis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foalders%2Fis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foalders%2Fis/lists"}