{"id":15551287,"url":"https://github.com/b2ns/libshell","last_synced_at":"2026-06-19T18:32:06.494Z","repository":{"id":37635477,"uuid":"486819977","full_name":"b2ns/libshell","owner":"b2ns","description":"basic lib functions for (bash)shell script","archived":false,"fork":false,"pushed_at":"2022-11-20T07:24:53.000Z","size":212,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-24T04:40:56.906Z","etag":null,"topics":["bash","color","command","function","import","lib","shell","string","tool","util"],"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/b2ns.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":"2022-04-29T03:04:38.000Z","updated_at":"2022-05-30T02:36:13.000Z","dependencies_parsed_at":"2022-07-10T15:32:26.563Z","dependency_job_id":null,"html_url":"https://github.com/b2ns/libshell","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/b2ns/libshell","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2ns%2Flibshell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2ns%2Flibshell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2ns%2Flibshell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2ns%2Flibshell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/b2ns","download_url":"https://codeload.github.com/b2ns/libshell/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2ns%2Flibshell/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34544403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","color","command","function","import","lib","shell","string","tool","util"],"created_at":"2024-10-02T14:03:57.026Z","updated_at":"2026-06-19T18:32:06.477Z","avatar_url":"https://github.com/b2ns.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://cdn.jsdelivr.net/gh/b2ns/libshell/assets/logo.svg\" alt=\"logo\" style=\"width: 100%; height: 250px;\"\u003e\n\n# libshell🚀\n\n![GitHub top language](https://img.shields.io/badge/bash-4EAA25?logo=GNU%20Bash\u0026logoColor=white\u0026color=\"brightgreen\"\u0026style=flat-square)\n![GitHub top language](https://img.shields.io/github/languages/top/b2ns/libshell?color=brightgreen\u0026style=flat-square)\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/b2ns/libshell/Publish?style=flat-square)\n![npm](https://img.shields.io/npm/dt/@b2ns/libshell?style=flat-square)\n![GitHub package.json version](https://img.shields.io/github/package-json/v/b2ns/libshell?style=flat-square)\n![GitHub](https://img.shields.io/github/license/b2ns/libshell?style=flat-square)\n\nbasic lib functions for (bash)shell script\n\n- [features](#features)\n- [download](#download)\n  - [from npm](#from-npm)\n  - [from github](#from-github)\n- [how to use](#how-to-use)\n- [api](#api)\n  - [Args](#args)\n  - [Array](#array)\n  - [Color](#color)\n  - [File](#file)\n  - [IO](#io)\n  - [Math](#math)\n  - [Path](#path)\n  - [String](#string)\n- [FAQ](#faq)\n- [build with](#build-with)\n- [acknowledgments](#acknowledgments)\n- [links](#links)\n\n## features\n\n- meant to be basic, small and easy to use\n- pure bash(4.3+), no magic, no external dependences\n- ECMAScript(Javascript) style like api\n- well tested\n- well documented\n- should be fast\n\n## download\n\n### from npm\n\n```sh\n# install in global\nnpm -g i @b2ns/libshell\n# or with yarn\nyarn global add @b2ns/libshell\n# or with pnpm\npnpm add -g @b2ns/libshell\n\n# source libshell directly in your script\nsource libshell\n\n\n# install in local project\nnpm i @b2ns/libshell\n# or with yarn\nyarn add @b2ns/libshell\n# or with pnpm\npnpm add @b2ns/libshell\n\n# source libshell from node_modules\nsource \"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" \u0026\u0026 pwd)/node_modules/@b2ns/libshell/libshell.sh\"\n```\n\n### from github\n\ndownload the latest release [here](https://github.com/b2ns/libshell/tags)\n\n## how to use\n\n```sh\n#!/usr/bin/env bash\nset -euo pipefail\nIFS=$'\\n\\t'\n\nsource libshell\n# or source like this if you don't install libshell to global\n# source \"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" \u0026\u0026 pwd)/rel/path/to/libshell.sh\"\n\n\n# after source libshell you get a `import` function and all libs builtin\n# use IMPORT_ALL_LIBS=0 to only get the `import` function\n# IMPORT_ALL_LIBS=0 source libshell\n\n# use `import` to include your own script\nimport /path/to/foo.sh\nimport ./path/to/bar.sh\nimport path/to/bar.sh\n\n# import at one line\nimport /path/to/x.sh ./path/to/y.sh path/to/z.sh\n\n# import builtin lib(you only need this when you set IMPORT_ALL_LIBS to 0)\nimport Array File Path String\n\n# let's use builtin lib functions here\nbasename=\"$(String_stripStart \"/foo/bar/libshell.sh\" \"*/\" 1)\" # libshell.sh\ndirname=\"$(String_stripEnd \"/foo/bar/libshell.sh\" \"/*\")\" # /foo/bar\nColor_print \"hello world\\n\" \"green\" \"italic\" \"bold\" \"bgBlack\"\n```\n\n## api\n\n### [Args](doc/Args.md)\n\ndefine and parse command arguments passed to your script.\n\n```sh\n# hello-world.sh\n\n# define command arguments\nArgs_define \"-j --job\" \"Running jobs\" \"\u003cint\u003e\" 2\nArgs_define \"-f --format\" \"Output format\" \"[json yaml toml xml]\" \"json\"\nArgs_define \"-v -V --version\" \"Show version\"\nArgs_define \"-h --help\" \"Show help\"\n\n# don't forget to parse the arguments passed in\nArgs_parse \"$@\"\n\n\n# let's deal with the arguments you got\nif Args_has \"-v\"; then\n  echo \"Version: 1.0.0\"\nfi\n\nif Args_has \"-h\" || (($# == 0)); then\n  # get help info based on what you defined above\n  Args_help\nfi\n\nif Args_has \"-f\"; then\n  format=\"$(Args_get \"--format\")\"\n  echo \"hello world\" \u003e \"foo.$format\"\nfi\n\n########################################\n# let's pass some arguments\n./hello-world.sh -h\n./hello-world.sh -v\n./hello-world.sh -f yaml\n./hello-world.sh -f=yaml\n./hello-world.sh -vhf yaml\n./hello-world.sh -vhf=yaml\n./hello-world.sh --job 8\n./hello-world.sh -j=8\n./hello-world.sh -j8\n```\n\nmore details in the [doc](doc/Args.md)\n\n### [Array](doc/Array.md)\n\n```sh\narr=(\"foo\" \"bar\" \"baz\")\n\nArray_isEmpty arr\n\nArray_includes arr \"bar\"\n\nArray_indexOf arr \"bar\" # 1\n\nArray_join arr \"/\" # foo/bar/baz\n\narr2=(2 5 1 3 4)\n\nArray_forEach arr2 echo # \"2 0\" \"5 1\" \"1 2\" \"3 3\" \"4 4\"\nArray_forEach arr2 'echo \"$1-$2\"' # \"2-0\" \"5-1\" \"1-2\" \"3-3\" \"4-4\"\n\nArray_map arr2 'echo \"$(($1 * 2))\"' # 2 10 2 6 8\n\nArray_push arr2 9 # 2 5 1 3 4 9\n\nArray_pop arr2 # 2 5 1 3\n\nArray_reverse arr2 # 4 3 1 5 2\n\nArray_sort arr2 # 1 2 3 4 5\n\nArray_splice arr2 1 1 # 2 1 3 4\n```\n\nmore details in the [doc](doc/Array.md)\n\n### [Color](doc/Color.md)\n\n```sh\ncoloredMsg=\"$(Color \"hello world\" \"yellowBright\" \"bgBlack\" \"italic\" \"underline\")\"\necho -e \"$coloredMsg\"\n\n# or just use Color_print\nColor_print \"hello world\\n\" \"yellowBright\" \"bgBlack\" \"italic\" \"underline\"\n\n# use rgb or hex color if your terminal supports it\nColor_print \"hello world\\n\" \"#fa0\" \"rgb(0,0,0)|bg\" \"bold\"\n```\n\nmore details in the [doc](doc/Color.md)\n\n### [File](doc/File.md)\n\n```sh\nFile_isDir \"foo/bar/\"\n\nFile_isFile \"foo/bar/baz.sh\"\n\nFile_isExist \"foo/bar/baz.sh\"\n\nFile_isSymlink \"foo/bar/baz.sh\"\n\nFile_isEmpty \"foo/bar/baz.sh\"\n```\n\nmore details in the [doc](doc/File.md)\n\n### [IO](doc/IO.md)\n\n```sh\nIO_log \"log\"\n\nIO_info \"info\"\n\nIO_warn \"warn\"\n\nIO_error \"error\"\n\n# also accept color format arguments\nIO_success \"success\" \"#0f0\" \"bold\"\n```\n\nmore details in the [doc](doc/IO.md)\n\n### [Math](doc/Math.md)\n\n```sh\nMath_abs -1 # 1\n\nMath_max 3 2 1 5 # 5\n\nMath_min 3 2 1 5 # 1\n\nMath_random 1 100\n\nMath_range 1 10 2\n```\n\nmore details in the [doc](doc/Math.md)\n\n### [Path](doc/Path.md)\n\n```sh\nPath_basename \"../foo/bar.sh\" # bar.sh\nPath_basename \"../foo/bar.sh\" \".sh\" # bar\n\nPath_extname \"../foo/bar.sh\" # .sh\n\nPath_dirname \"../foo/bar.sh\" # ../foo\n\nPath_join \"path/to/foo/\" \"../bar.sh\" # path/to/bar.sh\n\nPath_resolve \"path/to/foo/\" \"../bar.sh\" # /abs/path/to/bar.sh\n```\n\nmore details in the [doc](doc/Path.md)\n\n### [String](doc/String.md)\n\n```sh\nString_isEmpty \"foo\"\n\nString_includes \"foobar\" \"bar\"\n\nString_indexOf \"foobar\" \"bar\" # 3\n\nString_match \"foobar\" \"o{2,2}bar$\"\n\nString_replace \"foobar\" \"o\" \"x\" #fxobar\n\nString_slice \"foobar\" 1 4 # oob\n\nString_substr \"foobar\" 1 4 # ooba\n\nString_split \"foo-bar-baz\" \"-\" # (\"foo\" \"bar\" \"baz\")\n\nString_toLowerCase \"FOO\" # foo\n\nString_toUpperCase \"foo\" # FOO\n\nString_capitalize \"foo\" # Foo\n\nString_trim \"  foo bar  \" # foo bar\n\nString_stripStart \"/foo/bar/baz.sh\" \"*/\" 1 # baz.sh\n\nString_stripEnd \"/foo/bar/baz.sh\" \"/*\" # baz.sh\n```\n\nmore details in the [doc](doc/String.md)\n\n## FAQ\n\n- **why this repo?**  \n  I came form the javascript world, and I found myself always googling `truncate string in bash shell ?`, `difference between % and # ?`, `if String is empty, use -n or -z ?`:joy:.  \n  So here is this repo, to help writing shell script without google and pain.\n- **shoud I source libshell in every file?**  \n  No. you only need source it in the entry file.  \n  And there will be no harm if you source it everywhere.\n- **will it import the same module multiple times?**  \n  No. `import` only import module once.  \n  libshell will register the imported module and make sure it not being imported multiple times.\n- **feel slow when running in a loop?**  \n  It's a bash problem here.  \n  In bash `()`, `$()` or `|` will use subshell to execute. too many subshell will slow down your script.\n\n  ```sh\n  SECONDS=0\n  for ((i = 0; i \u003c 10000; i++)); do\n    # subshell used here\n    num=\"$(Math_random 0 10)\"\n  done\n  echo \"cost: ${SECONDS}s\"\n  # cost: 10s\n  ```\n\n  **workaround**: use the special global variable **`RETVAL`** to get the return value from the function\n\n  ```sh\n  SECONDS=0\n  for ((i = 0; i \u003c 10000; i++)); do\n    # invoke function directly and redirect stdout to /dev/null\n    Math_random 0 10 \u003e/dev/null\n    num=\"$RETVAL\"\n  done\n  echo \"cost: ${SECONDS}s\"\n  # cost: 0s\n  ```\n\n- **why xxx not included?**  \n  libshell meant to be basic. Only basic and general use function will be included.\n\n## build with\n\n- linter: [shellcheck](https://github.com/koalaman/shellcheck)\n- fixer: [shfmt](https://github.com/mvdan/sh)\n- unit test: [bats](https://github.com/bats-core/bats-core)\n\n## acknowledgments\n\n- [bash-oo-framework](https://github.com/niieani/bash-oo-framework)\n- [pure-sh-bible](https://github.com/dylanaraps/pure-sh-bible)\n- [chalk](https://github.com/chalk/chalk)\n- [commander](https://github.com/tj/commander.js)\n\n## links\n\n- [https://devhints.io/bash](https://devhints.io/bash)\n- [https://learnxinyminutes.com/docs/bash/](https://learnxinyminutes.com/docs/bash/)\n- [https://www.gnu.org/software/bash/manual/bash.html](https://www.gnu.org/software/bash/manual/bash.html)\n- [https://mywiki.wooledge.org](https://mywiki.wooledge.org)\n- [https://wiki.bash-hackers.org](https://wiki.bash-hackers.org)\n- [http://redsymbol.net/articles/unofficial-bash-strict-mode/](http://redsymbol.net/articles/unofficial-bash-strict-mode/)\n- [https://tldp.org/LDP/abs/html/index.html](https://tldp.org/LDP/abs/html/index.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb2ns%2Flibshell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fb2ns%2Flibshell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb2ns%2Flibshell/lists"}