npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@b2ns/libshell

v1.2.3

Published

basic lib functions for (bash)shell

Downloads

16

Readme

libshell🚀

GitHub top language GitHub top language GitHub Workflow Status npm GitHub package.json version GitHub

basic lib functions for (bash)shell script

features

  • meant to be basic, small and easy to use
  • pure bash(4.3+), no magic, no external dependences
  • ECMAScript(Javascript) style like api
  • well tested
  • well documented
  • should be fast

download

from npm

# install in global
npm -g i @b2ns/libshell
# or with yarn
yarn global add @b2ns/libshell
# or with pnpm
pnpm add -g @b2ns/libshell

# source libshell directly in your script
source libshell


# install in local project
npm i @b2ns/libshell
# or with yarn
yarn add @b2ns/libshell
# or with pnpm
pnpm add @b2ns/libshell

# source libshell from node_modules
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/node_modules/@b2ns/libshell/libshell.sh"

from github

download the latest release here

how to use

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

source libshell
# or source like this if you don't install libshell to global
# source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/rel/path/to/libshell.sh"


# after source libshell you get a `import` function and all libs builtin
# use IMPORT_ALL_LIBS=0 to only get the `import` function
# IMPORT_ALL_LIBS=0 source libshell

# use `import` to include your own script
import /path/to/foo.sh
import ./path/to/bar.sh
import path/to/bar.sh

# import at one line
import /path/to/x.sh ./path/to/y.sh path/to/z.sh

# import builtin lib(you only need this when you set IMPORT_ALL_LIBS to 0)
import Array File Path String

# let's use builtin lib functions here
basename="$(String_stripStart "/foo/bar/libshell.sh" "*/" 1)" # libshell.sh
dirname="$(String_stripEnd "/foo/bar/libshell.sh" "/*")" # /foo/bar
Color_print "hello world\n" "green" "italic" "bold" "bgBlack"

api

Args

define and parse command arguments passed to your script.

# hello-world.sh

# define command arguments
Args_define "-j --job" "Running jobs" "<int>" 2
Args_define "-f --format" "Output format" "[json yaml toml xml]" "json"
Args_define "-v -V --version" "Show version"
Args_define "-h --help" "Show help"

# don't forget to parse the arguments passed in
Args_parse "$@"


# let's deal with the arguments you got
if Args_has "-v"; then
  echo "Version: 1.0.0"
fi

if Args_has "-h" || (($# == 0)); then
  # get help info based on what you defined above
  Args_help
fi

if Args_has "-f"; then
  format="$(Args_get "--format")"
  echo "hello world" > "foo.$format"
fi

########################################
# let's pass some arguments
./hello-world.sh -h
./hello-world.sh -v
./hello-world.sh -f yaml
./hello-world.sh -f=yaml
./hello-world.sh -vhf yaml
./hello-world.sh -vhf=yaml
./hello-world.sh --job 8
./hello-world.sh -j=8
./hello-world.sh -j8

more details in the doc

Array

arr=("foo" "bar" "baz")

Array_isEmpty arr

Array_includes arr "bar"

Array_indexOf arr "bar" # 1

Array_join arr "/" # foo/bar/baz

arr2=(2 5 1 3 4)

Array_forEach arr2 echo # "2 0" "5 1" "1 2" "3 3" "4 4"
Array_forEach arr2 'echo "$1-$2"' # "2-0" "5-1" "1-2" "3-3" "4-4"

Array_map arr2 'echo "$(($1 * 2))"' # 2 10 2 6 8

Array_push arr2 9 # 2 5 1 3 4 9

Array_pop arr2 # 2 5 1 3

Array_reverse arr2 # 4 3 1 5 2

Array_sort arr2 # 1 2 3 4 5

Array_splice arr2 1 1 # 2 1 3 4

more details in the doc

Color

coloredMsg="$(Color "hello world" "yellowBright" "bgBlack" "italic" "underline")"
echo -e "$coloredMsg"

# or just use Color_print
Color_print "hello world\n" "yellowBright" "bgBlack" "italic" "underline"

# use rgb or hex color if your terminal supports it
Color_print "hello world\n" "#fa0" "rgb(0,0,0)|bg" "bold"

more details in the doc

File

File_isDir "foo/bar/"

File_isFile "foo/bar/baz.sh"

File_isExist "foo/bar/baz.sh"

File_isSymlink "foo/bar/baz.sh"

File_isEmpty "foo/bar/baz.sh"

more details in the doc

IO

IO_log "log"

IO_info "info"

IO_warn "warn"

IO_error "error"

# also accept color format arguments
IO_success "success" "#0f0" "bold"

more details in the doc

Math

Math_abs -1 # 1

Math_max 3 2 1 5 # 5

Math_min 3 2 1 5 # 1

Math_random 1 100

Math_range 1 10 2

more details in the doc

Path

Path_basename "../foo/bar.sh" # bar.sh
Path_basename "../foo/bar.sh" ".sh" # bar

Path_extname "../foo/bar.sh" # .sh

Path_dirname "../foo/bar.sh" # ../foo

Path_join "path/to/foo/" "../bar.sh" # path/to/bar.sh

Path_resolve "path/to/foo/" "../bar.sh" # /abs/path/to/bar.sh

more details in the doc

String

String_isEmpty "foo"

String_includes "foobar" "bar"

String_indexOf "foobar" "bar" # 3

String_match "foobar" "o{2,2}bar$"

String_replace "foobar" "o" "x" #fxobar

String_slice "foobar" 1 4 # oob

String_substr "foobar" 1 4 # ooba

String_split "foo-bar-baz" "-" # ("foo" "bar" "baz")

String_toLowerCase "FOO" # foo

String_toUpperCase "foo" # FOO

String_capitalize "foo" # Foo

String_trim "  foo bar  " # foo bar

String_stripStart "/foo/bar/baz.sh" "*/" 1 # baz.sh

String_stripEnd "/foo/bar/baz.sh" "/*" # baz.sh

more details in the doc

FAQ

  • why this repo?
    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:.
    So here is this repo, to help writing shell script without google and pain.

  • shoud I source libshell in every file?
    No. you only need source it in the entry file.
    And there will be no harm if you source it everywhere.

  • will it import the same module multiple times?
    No. import only import module once.
    libshell will register the imported module and make sure it not being imported multiple times.

  • feel slow when running in a loop?
    It's a bash problem here.
    In bash (), $() or | will use subshell to execute. too many subshell will slow down your script.

    SECONDS=0
    for ((i = 0; i < 10000; i++)); do
      # subshell used here
      num="$(Math_random 0 10)"
    done
    echo "cost: ${SECONDS}s"
    # cost: 10s

    workaround: use the special global variable RETVAL to get the return value from the function

    SECONDS=0
    for ((i = 0; i < 10000; i++)); do
      # invoke function directly and redirect stdout to /dev/null
      Math_random 0 10 >/dev/null
      num="$RETVAL"
    done
    echo "cost: ${SECONDS}s"
    # cost: 0s
  • why xxx not included?
    libshell meant to be basic. Only basic and general use function will be included.

build with

acknowledgments

links