{"id":13496025,"url":"https://github.com/xwmx/bash-boilerplate","last_synced_at":"2025-05-08T18:48:40.787Z","repository":{"id":43758362,"uuid":"30101799","full_name":"xwmx/bash-boilerplate","owner":"xwmx","description":"A collection of Bash scripts for creating safe and useful command line programs.","archived":false,"fork":false,"pushed_at":"2022-02-19T09:57:16.000Z","size":564,"stargazers_count":749,"open_issues_count":1,"forks_count":103,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-03-28T17:41:54.579Z","etag":null,"topics":["bash","boilerplate","boilerplate-scripts","command-line","linux","shell","unix"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/xwmx.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}},"created_at":"2015-01-31T04:10:27.000Z","updated_at":"2025-03-14T10:07:47.000Z","dependencies_parsed_at":"2022-08-22T08:01:32.064Z","dependency_job_id":null,"html_url":"https://github.com/xwmx/bash-boilerplate","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwmx%2Fbash-boilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwmx%2Fbash-boilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwmx%2Fbash-boilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwmx%2Fbash-boilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xwmx","download_url":"https://codeload.github.com/xwmx/bash-boilerplate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253133116,"owners_count":21859108,"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":["bash","boilerplate","boilerplate-scripts","command-line","linux","shell","unix"],"created_at":"2024-07-31T19:01:40.887Z","updated_at":"2025-05-08T18:48:40.765Z","avatar_url":"https://github.com/xwmx.png","language":"Shell","funding_links":[],"categories":["Shell","boilerplate"],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/xwmx/bash-boilerplate.svg?branch=master)](https://travis-ci.org/xwmx/bash-boilerplate)\n\nBash Boilerplate\n================\n\nA collection of Bash starter scripts for easily creating safe and useful\ncommand line programs.\n\nBash Boilerplate is great for making standalone, portable, single-file command line\nprograms as well as shell initialization functions. For a framework\napproach that's useful for task and build files, try [Bask](https://github.com/xwmx/bask),\na pure Bash mini-framework for command-centric Bash scripts.\n\n## Scripts\n\n### [bash-simple](https://github.com/xwmx/bash-boilerplate/blob/master/bash-simple)\n\nA simple bash script with some basic strictness checks and help features.\nUseful for simple programs that don't have many features and don't take\noptions other than help.\n\n###### Notable Features\n\n- Strict Mode,\n- Help template, printable with `-h` or `--help`.\n\n### [bash-simple-plus](https://github.com/xwmx/bash-boilerplate/blob/master/bash-simple-plus)\n\nA simple bash script with some basic strictness checks, option parsing,\nhelp features, easy debug printing. Useful for regular scripts.\n\n###### Notable Features\n\n- Strict Mode,\n- Help template, printable with `-h` or `--help`,\n- `debug` printing with `--debug` flag,\n- `_exit_1` and `_warn` functions for error messages,\n- Option parsing.\n\n### [bash-subcommands](https://github.com/xwmx/bash-boilerplate/blob/master/bash-subcommands)\n\nAn example of a bash program with subcommands. This contains lots of features\nand should be usable for creating bash programs that do multiple related\ntasks.\n\n###### Notable Features\n\n- Strict Mode,\n- Help template, printable with `-h` or `--help`,\n- `debug` printing with `--debug` flag,\n- `_exit_1` and `_warn` functions for error messages,\n- Option normalization and parsing,\n- Automatic arbitrary subcommand loading,\n- An nice, clean pattern for specifying per-subcommand help,\n- Built-in subcommands for help, version, and subcommand listing,\n- Conventions for distinguishing between functions and program subcommands,\n- Useful utility functions.\n\n### [functions.bash](https://github.com/xwmx/bash-boilerplate/blob/master/functions.bash)\n\nShell function examples and boilerplate. The functions in this file are\nintended to be included in the interactive shell, which can be done by\ndefining them in a shell init file like `~/.bashrc`.\n\n### [helpers.bash](https://github.com/xwmx/bash-boilerplate/blob/master/helpers.bash)\n\nHelper functions. These functions are primarily intended to be used within\nscripts, but can be adapted for use as shell functions.\n\n## Notes\n\n### ShellCheck\n\nUse it. It's super useful.\n\n\u003e ShellCheck is a static analysis and linting tool for sh/bash scripts.\nIt's mainly focused on handling typical beginner and intermediate level\nsyntax errors and pitfalls where the shell just gives a cryptic error\nmessage or strange behavior, but it also reports on a few more advanced\nissues where corner cases can cause delayed failures.\n\n#### Links\n\n- http://www.shellcheck.net/\n- http://www.shellcheck.net/about.html\n- https://github.com/koalaman/shellcheck\n\nIt can be used with Vim via\n[Syntastic](https://github.com/scrooloose/syntastic), Emacs via\n[Flycheck](https://github.com/flycheck/flycheck), Sublime Text 3 via\n[SublimeLinter](http://sublimelinter.readthedocs.org/en/latest/), VS Code via [vscode-shellcheck](https://github.com/timonwong/vscode-shellcheck), and Atom via\n[linter](https://atom.io/packages/linter),\n[atom-lint](https://atom.io/packages/atom-lint),\nor [linter-shellcheck](https://atom.io/packages/linter-shellcheck).\n\n---\n\n### Bash \"Strict Mode\"\n\nThese boilerplate scripts use some common settings for enforcing strictness\nin Bash scripts, thereby preventing some errors.\n\nFor some additional background, see Aaron Maxwell's\n[\"Unofficial Bash Strict Mode\" (redsymbol.net)\n](http://redsymbol.net/articles/unofficial-bash-strict-mode/)\npost.\n\n---\n\n#### Simple 'Strict Mode' TL;DR\n\nAdd this to the top of every script (note: an extended version of this is\nalready included in the boilerplate scripts):\n\n```bash\n# Bash 'Strict Mode'\n# http://redsymbol.net/articles/unofficial-bash-strict-mode\n# https://github.com/xwmx/bash-boilerplate#bash-strict-mode\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n```\n\n---\n\n#### `set -o nounset` / `set -u`\n\nTreat unset variables and parameters other than the special parameters `@` or\n`*` as an error when performing parameter expansion. An 'unbound variable'\nerror message will be written to the standard error, and a non-interactive\nshell will exit.\n\n##### Usage\n\nShort form:\n\n```bash\nset -u\n```\n\nLong form:\n\n```bash\nset -o nounset\n```\n\n##### Parameter Expansion\n\nParameter expansion can be used to test for unset variables when using `set -o nounset`.\n\nhttp://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion\n\nThe two approaches that are probably the most appropriate are:\n\n    ${parameter:-word}\n      If parameter is unset or null, the expansion of word is substituted.\n      Otherwise, the value of parameter is substituted. In other words, \"word\"\n      acts as a default value when the value of \"$parameter\" is blank. If \"word\"\n      is not present, then the default is blank (essentially an empty string).\n\n    ${parameter:?word}\n      If parameter is null or unset, the expansion of word (or a message to that\n      effect if word is not present) is written to the standard error and the\n      shell, if it is not interactive, exits. Otherwise, the value of parameter\n      is substituted.\n\n###### Parameter Expansion Examples\n\nArrays:\n\n```bash\n${some_array[@]:-}              # blank default value\n${some_array[*]:-}              # blank default value\n${some_array[0]:-}              # blank default value\n${some_array[0]:-default_value} # default value: the string 'default_value'\n```\n\nPositional variables:\n\n```bash\n${1:-alternative} # default value: the string 'alternative'\n${2:-}            # blank default value\n```\n\nWith an error message:\n\n```bash\n${1:?'error message'}  # exit with 'error message' if variable is unbound\n```\n\n---\n\n#### `set -o errexit` / `set -e`\n\nExit immediately if a pipeline returns non-zero.\n\n##### Usage\n\nShort form:\n\n```bash\nset -e\n```\n\nLong form:\n\n```bash\nset -o errexit\n```\n\n##### Using `set -o errexit` with `read -rd ''`\n\n`set -o errexit` is super useful for avoiding scary errors, but there are some\nthings to watch out for. When using `read -rd ''` with a heredoc, the\nexit status is non-zero, even though there isn't an error, and this\nsetting then causes the script to exit. `read -rd ''` is equivalent\nto `read -d $'\\0'`, which means read until it finds a NUL byte, but\nit reaches the end of the heredoc without finding one and exits with\na `1` status. Therefore, when reading from heredocs with `set -e`,\nthere are three potential solutions:\n\nSolution 1. `set +e` / `set -e` again:\n\n```bash\nset +e\nread -rd '' variable \u003c\u003cHEREDOC\nExample text.\nHEREDOC\nset -e\n```\n\nSolution 2. `\u003c\u003cHEREDOC || true`:\n\n```bash\nread -rd '' variable \u003c\u003cHEREDOC || true\nExample text.\nHEREDOC\n```\n\nSolution 3. Don't use `set -e` or `set -o errexit` at all.\n\nMore information:\n\n['builtin \"read -d\" behaves differently after \"set -e\"' (lists.gnu.org)\n](https://lists.gnu.org/archive/html/bug-bash/2013-02/msg00007.html)\n\n---\n\n#### `set -o pipefail`\n\nReturn value of a pipeline is the value of the last (rightmost) command to\nexit with a non-zero status, or zero if all commands in the pipeline exit\nsuccessfully.\n\n##### Usage\n\nLong form (no short form available):\n\n```bash\nset -o pipefail\n```\n\n---\n\n#### `$IFS`\n\nSet IFS to just newline and tab.\n\n```bash\nIFS=$'\\n\\t'\n```\n\nFor some background, see\n[Filenames and Pathnames in Shell: How to do it Correctly (dwheeler.com)\n](http://www.dwheeler.com/essays/filenames-in-shell.html)\n\n---\n\n### Misc Notes\n\nExplicitness and clarity are generally preferable, especially since bash can\nbe difficult to read. This leads to noisier, longer code, but should be\neasier to maintain. As a result, some general design preferences:\n\n- Use leading underscores on internal variable and function names in order\n  to avoid name collisions. For unintentionally global variables defined\n  without `local`, such as those defined outside of a function or\n  automatically through a `for` loop, prefix with double underscores.\n- Always use braces when referencing variables, preferring `${NAME}` instead\n  of `$NAME`. Braces are only required for variable references in some cases,\n  but the cognitive overhead involved in keeping track of which cases require\n  braces can be reduced by simply always using them.\n- Prefer `printf` over `echo`. For more information, see:\n  http://unix.stackexchange.com/a/65819\n- Prefer `$_explicit_variable_name` over names like `$var`.\n- Use the `#!/usr/bin/env bash` shebang in order to run the preferred\n  Bash version rather than hard-coding a `bash` executable path.\n- Prefer splitting statements across multiple lines rather than writing\n  one-liners.\n- Group related code into sections with large, easily scannable headers.\n- Describe behavior in comments as much as possible, assuming the reader is\n  a programmer familiar with the shell, but not necessarily experienced writing\n  shell scripts.\n\n### Resources\n\n- [About ShellCheck (shellcheck.net)](http://www.shellcheck.net/about.html)\n- [Bash Reference Manual (gnu.org)](http://www.gnu.org/software/bash/manual/bashref.html)\n- [POSIX: Shell Command Language (pubs.opengroup.org)\n](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html)\n- [The Art of Command Line (github.com)](https://github.com/jlevy/the-art-of-command-line)\n- [\"Unofficial Bash Strict Mode\" (redsymbol.net)\n](http://redsymbol.net/articles/unofficial-bash-strict-mode/)\n- [Filenames and Pathnames in Shell: How to do it Correctly (dwheeler.com)\n](http://www.dwheeler.com/essays/filenames-in-shell.html)\n- [Understanding Exit Codes and how to use them in bash scripts (bencane.com)\n](http://bencane.com/2014/09/02/understanding-exit-codes-and-how-to-use-them-in-bash-scripts/)\n- ['builtin \"read -d\" behaves differently after \"set -e\"' (lists.gnu.org)\n](https://lists.gnu.org/archive/html/bug-bash/2013-02/msg00007.html)\n- [Bash Pitfalls (mywiki.wooledge.org)\n](http://mywiki.wooledge.org/BashPitfalls)\n- [Rich’s sh (POSIX shell) tricks (etalabs.net)](http://www.etalabs.net/sh_tricks.htm)\n- [Writing Robust Bash Shell Scripts (davidpashley.com)](http://www.davidpashley.com/articles/writing-robust-shell-scripts/)\n- [Bash Strict Mode (github.com)](https://github.com/tests-always-included/wick/blob/master/doc/bash-strict-mode.md)\n- [pure bash bible - A collection of pure bash alternatives to external processes (github.com)](https://github.com/dylanaraps/pure-bash-bible)\n\n### Related Projects\n\n- [oxyc/bash-boilerplate](https://github.com/oxyc/bash-boilerplate)\n- [e36freak/templates](https://github.com/e36freak/templates)\n- [connermcd/bash-boilerplate](https://github.com/connermcd/bash-boilerplate)\n- [chrisopedia/bash-boilerplate](https://github.com/chrisopedia/bash-boilerplate)\n- [ShaneKilkelly/manuel](https://github.com/ShaneKilkelly/manuel)\n- [kvz/bash3boilerplate](https://github.com/kvz/bash3boilerplate)\n- [ralish/bash-script-template](https://github.com/ralish/bash-script-template)\n\n### Examples\n\nScripts based on this project.\n\n- [airport](https://github.com/xwmx/airport) - A command line tool for Wi-Fi on macOS.\n- [bask](https://github.com/xwmx/bask) - A pure Bash mini-framework for command-centric Bash scripts.\n- [bindle](https://github.com/xwmx/bindle) - A configuration and dotfile management tool for your personal unix-like computer.\n- [hosts](https://github.com/xwmx/hosts) - Command line hosts file editor in a single portable script.\n- [❯ nb](https://github.com/xwmx/nb) - CLI note-taking, bookmarking, and archiving with encryption, advanced search, Git-backed versioning and syncing, Pandoc-backed conversion, and more in a single portable script.\n- [notes-app-cli](https://github.com/xwmx/notes-app-cli) - A command line interface for Notes.app on macOS.\n- [pb](https://github.com/xwmx/pb) - A tiny wrapper combining pbcopy \u0026 pbpaste in a single command.\n- [search.sh](https://github.com/xwmx/search.sh) - A command line search multi-tool.\n- [user](https://github.com/xwmx/user) - Command line interface for common macOS user account operations.\n- [vbox](https://github.com/xwmx/vbox) - A streamlined interface for VBoxManage, the VirtualBox command line tool.\n\n---\n\nCopyright (c) 2015 William Melody • hi@williammelody.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxwmx%2Fbash-boilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxwmx%2Fbash-boilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxwmx%2Fbash-boilerplate/lists"}