{"id":17823374,"url":"https://github.com/purarue/on_machine","last_synced_at":"2025-03-18T16:30:28.287Z","repository":{"id":38524009,"uuid":"501928387","full_name":"purarue/on_machine","owner":"purarue","description":"Generate a unique-enough fingerprint for my current machine, to make it easier to pick different commands/scripts to run on mac, different flavors or linux, or windows","archived":false,"fork":false,"pushed_at":"2024-10-25T17:36:38.000Z","size":60,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-16T21:48:22.223Z","etag":null,"topics":["detection","distro","dotfiles","linux-distros","operating-system","operating-system-detection"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/purarue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2022-06-10T06:36:50.000Z","updated_at":"2025-03-04T12:51:08.000Z","dependencies_parsed_at":"2024-10-27T18:22:37.244Z","dependency_job_id":"48810a05-37bc-43f5-91f6-d02e6b862b94","html_url":"https://github.com/purarue/on_machine","commit_stats":null,"previous_names":["seanbreckenridge/on_machine"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purarue%2Fon_machine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purarue%2Fon_machine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purarue%2Fon_machine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purarue%2Fon_machine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/purarue","download_url":"https://codeload.github.com/purarue/on_machine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244259791,"owners_count":20424616,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["detection","distro","dotfiles","linux-distros","operating-system","operating-system-detection"],"created_at":"2024-10-27T17:57:49.175Z","updated_at":"2025-03-18T16:30:28.281Z","avatar_url":"https://github.com/purarue.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## on_machine\n\nA helper CLI tool to determine which computer you're currently on. Often in ones dotfiles or personal scripts, you do something like:\n\n```bash\ncase \"$(uname -s)\" in\n  Linux) command_on_linux ;;\n  Darwin) command_on_mac ;;\n  *) echo 'unknown...' ;;\nesac\n```\n\n...to run particular commands on different machines/installs.\n\nThis is fine if you're always going to have two installs, but as you add more it starts to get more and more complicated. For example, I have:\n\n- multiple linux installs (for example one on `Ubuntu` and another on `Arch`)\n- [termux](https://termux.com/) on my phone\n- [`wsl`](https://docs.microsoft.com/en-us/windows/wsl/install) will also return `Linux`, when you likely want to do something custom on windows\n\nSo, `on_machine` generates a unique-enough fingerprint of your system (which you can tune to be as simple or complicated as you want), so you can do:\n\n```bash\ncase \"$(on_machine)\" in\n  linux_arch_*) command_on_arch ;;\n  linux_ubuntu_*) command_on_ubuntu ;;\n  android_termux_*) command_on_termux ;;\n  windows_*) command_on_wsl ;;\n  mac_*) command_on_mac ;;\nesac\n```\n\nThis borrows a lot of ideas from tools like [`neofetch`](https://github.com/dylanaraps/neofetch) to figure out what operating system/distribution one is using\n\n### Install\n\nUsing `go install` to put it on your `$GOBIN`:\n\n`go install github.com/purarue/on_machine/cmd/on_machine@latest`\n\nI recommend you have both `uname` and `lsb_release` installed if possible on `linux`, that makes distribution detection much nicer. Otherwise, this defaults to the `golang` `runtime` module defaults\n\nTo manually build:\n\n```bash\ngit clone https://github.com/purarue/on_machine\ncd ./on_machine\ngo build ./cmd/on_machine\n# copy binary somewhere on your $PATH\nsudo cp ./on_machine /usr/local/bin\n```\n\n## Usage\n\n```\nusage: on_machine [-h] [-cmd \u003cprint|match\u003e] [OPTIONS] [PATTERN]\n\nTool to determine which operating system/machine you're on.\n\nCommands:\nprint [default]: prints the computed fingerprint after interpolating the pattern '%o_%d_%h'\nmatch: does directory/path matching based on the pattern, changes the default pattern to '%o/%d/%h'\n\nprint\n---\nPATTERN is a printf-styled format string, supporting the following sequences:\n\n%o - Operating System (using uname)\n%d - Distro (using lsb_release)\n%h - Hostname (name of the computer)\n%a - Arch (detected by golang)\n%O - Golang OS (unmodified golang detected operating system)\n\nBy default, this uses '%o_%d_%h'\n\nmatch\n---\nDirectory/path matching, Uses the pattern to match directory structures.\nCan provide the base path to use with -base, that replaces '/' with\nOS-specific path separator in the pattern. For more information, see the docs:\nhttps://github.com/purarue/on_machine\n\nOptions:\n\n  -base string\n    \tbase directory to use to match paths\n  -cmd string\n    \ton_machine command to run (default \"print\")\n  -delimiter string\n    \tdelimiter to print between matches (default \"\\n\")\n  -filter string\n    \tfilter matches to either 'dir' or 'file'\n  -json\n    \tprint matches as a JSON array\n  -print0\n    \tuse the null character as the delimiter\n  -skip-last-delim\n    \tdont print the delimiter after the last match\n```\n\nFor basic usage, can just run `on_machine` with no arguments, using a `case` statements\n\n```bash\ncase \"$(on_machine)\" in\n  linux_arch_*) command_on_arch ;;\n  linux_ubuntu_*) command_on_ubuntu ;;\n  android_termux_*) command_on_termux ;;\n  windows_*) command_on_wsl ;;\n  mac_*) command_on_mac ;;\nesac\n\n# or, for example, to skip running a command on android and run everywhere else\ncase \"$(on_machine)\" in\n  android_*) ;;\n  *) command_to_run_everywhere_else ;;\nesac\n```\n\nSometimes the `hostname` cannot be determined (e.g. on android), so if you'd like you can set something custom, you can use the `ON_MACHINE_HOSTNAME`, e.g., in your shell startup:\n\n```bash\nON_OS=\"$(on_machine)\"\n[[ \"$ON_OS\" =~ ^android.* ]] \u0026\u0026 export ON_MACHINE_HOSTNAME=\"phone\"\n```\n\n```bash\n$ on_machine\nandroid_termux_phone\n```\n\n### match\n\nThis can be thought of as an alternative to the above, its a different way to figure out what code to run on different machines, by placing scripts in a particular directory structure\n\nYou can manually do case/regex statements in bash (and often that is enough), but in some cases that can become complicated. I use this to match [background processes](https://github.com/purarue/bgproc) scripts on different machines -- to figure out which bash scripts to run. Those are organized like:\n\n```\nmatching_examples/dir_based\n├── all\n│   └── this_dir_is_matched_everytime\n├── android\n│   └── on_android\n├── linux\n│   ├── arch\n│   │   ├── home\n│   │   │   └── on_arch_when_hostname_is_home\n│   │   ├── only_on_arch\n│   │   └── work\n│   │       └── on_arch_when_hostname_is_work\n│   ├── matched_on_any_linux_install\n│   └── ubuntu\n│       └── only_on_ubuntu\n└── mac\n    └── on_mac\n```\n\nThen, say my hostname is `home`, and I'm on my `arch` machine. The `match` command computes the following:\n\n```bash\n$ on_machine -cmd match -base ./matching_examples/dir_based '%o/%d/%h'\n/home/username/Repos/on_machine/matching_examples/dir_based/all\n/home/username/Repos/on_machine/matching_examples/dir_based/linux\n/home/username/Repos/on_machine/matching_examples/dir_based/linux/arch\n/home/username/Repos/on_machine/matching_examples/dir_based/linux/arch/home\n```\n\nNote: `all` is like a `*`, its always matched -- so that would be where I store shared jobs.\n\n[`bgproc_on_machine`](https://github.com/purarue/bgproc/blob/master/bgproc_on_machine) uses multiple directories to organize different jobs. That uses on_machine internally like:\n\n```bash\nMATCHES=()\nwhile read -r -d $'\\0' match; do\n\tMATCHES+=(\"$match\")\ndone \u003c \u003c(on_machine -cmd match -print0 -filter dir -base \"$base\" '%o/%d')\n```\n\n... which figures out which directories/scripts to include when running jobs:\n\n```\n$ bgproc_on_machine -o\n1655993990:Searching for jobs in:\n1655993990:/home/username/data/jobs/all\n1655993990:/home/username/data/jobs/linux\n1655993990:/home/username/.local/scripts/supervisor_jobs/all\n1655993990:/home/username/.local/scripts/supervisor_jobs/linux\n1655993990:/home/username/Repos/HPI-personal/jobs/all\n1655993990:/home/username/Repos/HPI-personal/jobs/linux\n```\n\nFor a real example of one of these directory structures, see [my HPI jobs](https://github.com/purarue/HPI-personal/tree/master/jobs)\n\nIf the pattern includes an extension, this extracts that and tries to match at each level going down. For example, for setting up your `~/.zshrc` setup: I want some code that runs everywhere (`all.zsh`), some that runs on `android`, some that runs on `linux`, and then additional code that runs on `linux` and `arch`. So, given:\n\n```\n./matching_examples/with_extensions\n├── all.zsh\n├── android.zsh\n├── linux\n│   ├── arch.zsh\n│   └── ubuntu.zsh\n├── linux.zsh\n└── mac.zsh\n```\n\nOn my arch machine, using the pattern `%o/%d.zsh`, this matches:\n\n```bash\n$ on_machine -cmd match -base ./matching_examples/with_extensions -filter file '%o/%d.zsh\n/home/username/Repos/on_machine/matching_examples/with_extensions/all.zsh\n/home/username/Repos/on_machine/matching_examples/with_extensions/linux/arch.zsh\n/home/username/Repos/on_machine/matching_examples/with_extensions/linux.zsh\n```\n\nEssentially, this lets me pick what scripts to run organized as a directory, instead of ever-growing `case` statement in a `bash` script somewhere.\n\n## Contributing\n\nI test this on all my machines, but it gets increasingly difficult to test on systems I don't have access to.\n\nIf you're able to test this on some operating system not listed above, or use one this doesn't support, am happy to accept PRs for new operating systems, or possible strategies to detect new systems based on some command output/metadata file that exists\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurarue%2Fon_machine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpurarue%2Fon_machine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurarue%2Fon_machine/lists"}