{"id":15042430,"url":"https://github.com/jazzschmidt/skeleton-bash","last_synced_at":"2025-04-14T20:33:36.383Z","repository":{"id":48323596,"uuid":"387056840","full_name":"jazzschmidt/skeleton-bash","owner":"jazzschmidt","description":"Bash script library for authoring versatile and easy-to-use cli programs.","archived":false,"fork":false,"pushed_at":"2021-08-05T15:11:51.000Z","size":649,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-18T09:02:29.228Z","etag":null,"topics":["bash","bash-hacks","bash-script","bash-scripting","framework","library"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jazzschmidt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-17T23:53:56.000Z","updated_at":"2023-01-03T16:22:20.000Z","dependencies_parsed_at":"2022-09-08T12:31:13.790Z","dependency_job_id":null,"html_url":"https://github.com/jazzschmidt/skeleton-bash","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzschmidt%2Fskeleton-bash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzschmidt%2Fskeleton-bash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzschmidt%2Fskeleton-bash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzschmidt%2Fskeleton-bash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jazzschmidt","download_url":"https://codeload.github.com/jazzschmidt/skeleton-bash/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248956346,"owners_count":21189333,"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","bash-hacks","bash-script","bash-scripting","framework","library"],"created_at":"2024-09-24T20:47:17.912Z","updated_at":"2025-04-14T20:33:36.361Z","avatar_url":"https://github.com/jazzschmidt.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Executing the hello command](assets/logo.png)\n\n# skeleton:bash - Bash Script Framework\n\n**skeleton:bash** is a small, declarative framework that aims at providing the look-and-feel of\nany other *nix tool you and your users are used to.\nIt offers a convenient way to structure and organize your bash scripts and assists\nyou in writing versatile and easy-to-use programs.\n\nWhats most important: it generates usage information for you and your scripts users.\n\n## Installation\n\nFor convenience you can simply install the script via npm, which adds the\n`skeleton-bash-path` command, returning the path to skeleton:bash.\n\n```bash\n#!/usr/bin/env bash\n\ncommand -v skeleton-bash-path \u0026\u003e /dev/null || npm install -g --save skeleton-bash-npm\nsource \"$(skeleton-bash-path)\"\n\n# ...\n```\n\n## Features\n\n**skeleton:bash** makes it easy to\n- [parse and validate flag and parameter options](#parsing-options)\n- generate extensive usage information\n- [write scripts with different sub commands](#adding-commands-and-subcommands)\n- [setup and cleanup the environment](#helper-functions)\n- [debug and trace your script](#debugging-and-tracing)\n\nIn addition to that, it offers functions to [colorize output and emit error messages](#helper-functions).  \n\n## Examples\nSuppose this executable (chmod +x) `example.sh`:\n\n```bash\n#!/usr/bin/env bash\n\nsource skeleton.sh\n\nfunction @greet() {\n  description \"Displays a greeting\"\n  param \"name\" \"n\" \"name\" \"greets \u003cname\u003e instead of the current user\"; name=\"$param\"\n\n  execute() {\n    echo \"Hello ${name:-$(whoami)}\"\n  }\n}\n```\n\n**Executing the greet command**\n\nThe **greet** command will receive the parameter `name|n` and also shows them when\nrunning `./example.sh greet --help`.\n\n![Executing the greet command](assets/example-1.gif)\n\nAlso, the **greet** command is listed in the global help page:\n\n![Showing the script help](assets/example-2.png)\n\nInstead of using named parameters, your commands can also be configured to receive\narguments:\n\n```bash\nfunction @greet() {\n  description \"Displays a greeting\"\n  args \"NAME\"\n\n  execute() {\n    echo \"Hello ${1}\"\n  }\n\n  help() {\n    echo \"Greets the given NAME\"\n  }\n}\n```\n\nSince we added the `help` function, a help message other than the default description\ntells the user that he can provide the **NAME** argument.\n\n![Using options](assets/example-3.png)\n\n## Adding Commands and Subcommands\n\nEvery `@function` will be added as a command to your script. The script will fail, if\nyou don't provide a description. Nesting commands is a matter of renaming the command:\n\n```bash\nfunction @books() {\n  description \"Book Management\"\n}\n\nfunction @books-list() {\n  command \"books list\"\n  description \"Lists books\"\n\n  execute() {\n    :\n  }\n}\n\nfunction @books-create() {\n  command \"books create\"\n  description \"Creates a book\"\n\n  execute() {\n    :\n  }\n}\n```\n\n![Adding subcommands](assets/example-4.png)\n\n## Parsing Options\n\nDefining options is pretty straightforward in **skeleton:bash**:\n```bash\nfunction @command {\n    flag \"s\" \"silent\" \"silences output\"\n    declare silent=$flag # true if either -s or --silent is present, false otherwise\n\n    flag \"v\" \"increases verbosity\"\n    declare verbose=$flag # only true, when -v is set; short and long args are interchangeable\n\n    param \"n\" \"name\" \"string\" \"sets the name\"\n    declare name=${param:-default} # the value of -n or --name or just 'default'\n    # multiple values may be read with ${param[*]} or ${param[@]}\n\n    param \"max-age\" \"integer\" \"sets max-age\"\n    local max_age=${arg:-} # the value of --max-age if present\n\n    # ...\n}\n```\n\nShort options can be passed with the shorthand syntax `-abc`. If you provide an\noption, that is not declared in your command an error message will be shown:\n\n![Unknown options error](assets/example-5.png)\n\nThe global variables `$flag` and `$param` will hold the value directly after the\nrespective registering function has been called.\n\nOptions from command functions should be saved as global variables to remain usable\nfor the `execute` function like shown in the example above.\n\n## Commands and special Functions\n\nThere are a few special functions:\n\n|Function|Description|\n|---|---|\n|`setup`|Bootstraps the script, can be used to define global options|\n|`teardown`|Will be called when the script exits|\n|`main`|Will be called instead of usage page when script is being called without command |\n\n*Notice*: When using the `teardown` function, it is necessary to call `__main` at the bottom\nof your script!\n\n### Helper Functions\n\n|Function|Description|\n|---|---|\n|`error`|Emits red error messages to stderr along with its origin function name|\n|`debug`|Logs an orange/brown debug message|\n|`colorize`|Colorizes output; can also be used as pipe|\n|`red`, `green`, `blue`, ...|*see above*|\n|`has_flag`|Sets `$flag` to `true` when the flag option exists, false otherwise|\n|`get_param`|Sets `$param` to the param values if present|\n|`array_contains`|Returns `true` if the array `$2` contains `$1`|\n\n## Debugging and Tracing\n\nWhen called with `DEBUG` set to one of `1`, `true`, `yes` or `y`, debug messages\nare shown and colorized. They are formatted like:\n\n**`[DEBUG] \u003cscript-name\u003e \u003ccommand_function\u003e: \u003cmessage\u003e`**\n\nSince debugging of bash script can be pretty hard, you can also enable tracing by\nsupplying the `TRACE` parameter just like the debug parameter, which will enable\ntracing as soon as the script enters your command.\n\n```bash\nfunction @hello() {\n  description \"Hello world\"\n\n  execute() {\n    debug \"Command @hello started\"\n    echo \"Hello world\"\n  }\n}\n```\n\n![Debugging and tracing](assets/example-6.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzschmidt%2Fskeleton-bash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjazzschmidt%2Fskeleton-bash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzschmidt%2Fskeleton-bash/lists"}