{"id":17422227,"url":"https://github.com/alexzhangs/xsh","last_synced_at":"2025-04-11T23:20:28.040Z","repository":{"id":46507947,"uuid":"114113745","full_name":"alexzhangs/xsh","owner":"alexzhangs","description":"eXtension of baSH","archived":false,"fork":false,"pushed_at":"2024-03-14T21:34:46.000Z","size":464,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T19:11:14.334Z","etag":null,"topics":["bash","framework","library","shell","xsh"],"latest_commit_sha":null,"homepage":"https://xsh.0xbeta.com","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/alexzhangs.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":"2017-12-13T11:40:44.000Z","updated_at":"2025-02-23T17:28:27.000Z","dependencies_parsed_at":"2024-03-14T22:43:22.171Z","dependency_job_id":"b7377336-080a-4b6f-a496-8a0c83519f2b","html_url":"https://github.com/alexzhangs/xsh","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhangs%2Fxsh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhangs%2Fxsh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhangs%2Fxsh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhangs%2Fxsh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexzhangs","download_url":"https://codeload.github.com/alexzhangs/xsh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248493027,"owners_count":21113184,"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","framework","library","shell","xsh"],"created_at":"2024-10-17T03:14:03.620Z","updated_at":"2025-04-11T23:20:28.020Z","avatar_url":"https://github.com/alexzhangs.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub tag](https://img.shields.io/github/v/tag/alexzhangs/xsh?sort=date)](https://github.com/alexzhangs/xsh/tags)\n[![GitHub](https://img.shields.io/github/license/alexzhangs/xsh.svg?style=flat-square)](https://github.com/alexzhangs/xsh/)\n[![GitHub last commit](https://img.shields.io/github/last-commit/alexzhangs/xsh.svg?style=flat-square)](https://github.com/alexzhangs/xsh/commits/master)\n\n[![Travis (.com)](https://img.shields.io/travis/com/alexzhangs/xsh/master.svg?style=flat-square)](https://travis-ci.com/alexzhangs/xsh/)\n[![codecov](https://codecov.io/gh/alexzhangs/xsh/branch/master/graph/badge.svg?token=HVTO788DLV)](https://codecov.io/gh/alexzhangs/xsh)\n[![CodeFactor](https://www.codefactor.io/repository/github/alexzhangs/xsh/badge)](https://www.codefactor.io/repository/github/alexzhangs/xsh)\n[![GitHub issues](https://img.shields.io/github/issues/alexzhangs/xsh.svg?style=flat-square)](https://github.com/alexzhangs/xsh/issues)\n[![GitHub pull requests](https://img.shields.io/github/issues-pr/alexzhangs/xsh.svg?style=flat-square)](https://github.com/alexzhangs/xsh/pulls)\n\n| Linux Ubuntu Bionic 18.04 - bash 4.4.20 | macOS 10.15.7 - bash 3.2.57 |\n|-----------------------------------------|-----------------------------|\n| [![Build1][1]][0]                       | [![Build2][2]][0]           |\n\n[0]: https://travis-ci.com/alexzhangs/xsh\n[1]: https://travis-matrix-badges.herokuapp.com/repos/alexzhangs/xsh/branches/master/1?use_travis_com=true\n[2]: https://travis-matrix-badges.herokuapp.com/repos/alexzhangs/xsh/branches/master/2?use_travis_com=true\n\n\n# e\u003cspan style=\"color:red\"\u003eX\u003c/span\u003etension of ba\u003cspan style=\"color:red\"\u003eSH\u003c/span\u003e\n\nxsh is an e\u003cspan style=\"color:red\"\u003e__x__\u003c/span\u003etension of ba\u003cspan style=\"color:red\"\u003e__sh__\u003c/span\u003e. It works as a bash library framework.\n\nxsh aimed to provide a uniform and easy way to reuse bash code, like what a library does.\n\nxsh - this repository, in a narrow sense, is not a library itself. It's just a framework, in a broad sense xsh along with other repositories, such as `xsh-lib/core` as a whole, is a bash library with a framework.\n\nWhy started this?\n\nIt is the only way I can write comfortable shellcode quickly for different purpose, and keep them well-organized as they grow, and be able to be reused at the time they are needed again.\n\n![xsh usage](/assets/images/xsh-usage.png)\n\nThis project is still at version `0.x`, and should be considered immature.\n\n\n\n## 2. Design Philosophy\n\n* Reuse the shellcode previously written, provide a uniform way to organize the code, document the code, format the code, execute the code, even the way you write the code. As a result, some well-organized bash code libraries will be born.\n\n* Easy to bootstrap(install).\n\n  The only thing you need is a bash and Git client.\n\n  ```bash\n  $ git clone https://github.com/alexzhangs/xsh\n  $ bash xsh/install.sh\n  $ . ~/.xshrc\n  ```\n\n* Easy to invoke.\n\n  E.g. Call a utility named `upper` under the package `string` in the library `x` :\n\n  ```bash\n  $ xsh x/string/upper 'hello world'\n\n  HELLO WORLD\n  ```\n\n* Easy to understand how it works.\n\n  __xsh framework__, in technical, is just a single function, called `xsh()`, the only function inside `xsh.sh`.\n\n  Through `xsh()`, it's able to load/unload libraries, call utilities of libraries, and get help.\n\n  __xsh libraries__, are some Git repositories, hosted online, contain some `.sh` files, called utilities, present as functions and scripts, organized with some simple rules.\n\n  You can build your libraries with your Git repositories.\n\n* Easy to make your existing code a library.\n\n  A xsh library is just a Git repo following some simple rules. The rules will be talked about later in the development section. Any repos following that rules can be able to load as xsh libraries.\n\n\n\n### 2.1. What does xsh Framework Do?\n\n* Provide an easy way to document and represent help and usage info\n* Support basic logging\n* Support debugging\n* Support library versioning\n* Handle the load/unload/update of libraries\n\n\n\n### 2.2. What do xsh Libraries Do?\n\n* Provide a container for utilities\n* Provide rules for organizing utilities by packages\n\nThe xsh framework supports both public and private libraries.\n\n\n\n### 2.3 What do xsh Utilities Do?\n\n* Provide the fundamental function\n* Provide help and usage information\n* Handle temporary files\n* Handle logs\n* Handle output\n\nOf course, some of the above topics can be built as libraries, packages, or utilities themselves.\n\n\n\n## 3. xsh Bootstrap/Installation\n\nThe only thing you need is a bash and Git client.\n\n```bash\n$ git clone https://github.com/alexzhangs/xsh\n$ bash xsh/install.sh\n$ . ~/.xshrc\n```\n\nOr bootstrap xsh with a single line:\n\n```\n$ curl -s https://raw.githubusercontent.com/alexzhangs/xsh/master/boot | bash \u0026\u0026 . ~/.xshrc\n```\n\n\n\n## 4. xsh Usage\n\nBefore you can do something useful with xsh, you must load some libraries.\n\n\n\n### 4.1. Load xsh Libraries\n\nUse the `xsh load` command to load a library.\n\nLoading the latest tagged version of the library [xsh-lib/core](https://github.com/xsh-lib/core), you should issue:\n\n```bash\n$ xsh load xsh-lib/core\n\nCloning into '/Users/alex/.xsh/repo/xsh-lib/core'...\nremote: Enumerating objects: 401, done.\nremote: Counting objects: 100% (401/401), done.\nremote: Compressing objects: 100% (237/237), done.\nremote: Total 1276 (delta 149), reused 367 (delta 133), pack-reused 875\nReceiving objects: 100% (1276/1276), 165.74 KiB | 18.00 KiB/s, done.\nResolving deltas: 100% (516/516), done.\nDeleted tag '0.1.0' (was 5e7dcfb)\nFrom https://github.com/xsh-lib/core\n * [new tag]         0.1.0      -\u003e 0.1.0\n__xsh_git_force_update: INFO: Already at the latest version: 0.1.0.\n```\n\nLoading the latest development state of the library [xsh-lib/core](https://github.com/xsh-lib/core) on default branch `master`, you should issue:\n\n```bash\n$ xsh load -b master xsh-lib/core\n```\n\nAfter the lib is loaded, you can use the `xsh list` command to list all loaded libraries.\n\n```bash\n$ xsh list\n\nx (0.1.0) =\u003e xsh-lib/core\n```\n\nTo list all the utilities of the library `x`, use:\n\n```bash\n$ xsh list x\n\n[script] x/log/filter\n[functions] x/string/lower\n[functions] x/string/random\n[functions] x/string/upper\n[functions] x/string/uuid\n...\n```\n\n\n\n#### 4.1.1. Update the Loaded xsh Libraries\n\nUse the `xsh update` command to update loaded libraries.\n\nTo update the previously loaded library `xsh-lib/core`, simply issue:\n\n```\n$ xsh update xsh-lib/core\n\nDeleted tag '0.1.0' (was 5e7dcfb)\nFrom https://github.com/xsh-lib/core\n * [new tag]         0.1.0      -\u003e 0.1.0\n__xsh_git_force_update: INFO: Already at the latest version: 0.1.0.\n```\n\n\n\n#### 4.1.2. Unload the loaded xsh Libraries\n\nUse the `xsh unload` command to unload loaded libraries.\n\nTo unload the previously loaded library `xsh-lib/core`, simply issue:\n\n```bash\n$ xsh unload xsh-lib/core\n```\n\n\n\n### 4.2. Invoke xsh Utilities\n\nThere are two methods to invoke xsh utilities.\n\nBefore to talk about that, let's get familiar with the glossary `LPUE`, `LPUR`, and `LPUC`.\n\n* LPUE stands for `Lib/Package/Util Expression`,  a LPUE example for the library `xsh-lib/core` is `x/string/upper`.\n\n* LPUR stands for `Lib/Package/Util Regex`,  a LPUR example for the library `xsh-lib/core` is `x/string` that matches all the utilities under the package string.\n\n* LPUC stands for `Lib/Package/Util Callable`, a LPUC example for the library `xsh-lib/core` is `x-string-upper`.\n\nNow let's get back to the three methods:\n\n1. Call an individual LPUE.\n\n   The syntax:\n\n   ```bash\n   $ xsh \u003cLPUE\u003e [options]\n   ```\n\n   A sample:\n\n   ```bash\n   $ xsh x/string/upper 'hello world'\n\n   HELLO WORLD\n   ```\n\n1. Call a LPUC without the leading `xsh` command.\n\n   The syntax:\n\n   ```bash\n   \u003cLPUC\u003e [options]\n   ```\n\n   In order to call a LPUC directly, you must import the LPUE first.\n\n   Use command `xsh imports` to import LPUEs. Afterward, you can call them directly as the syntax: `\u003clib\u003e-\u003cpackage\u003e-\u003cutil\u003e`.\n\n   A sample:\n\n   ```bash\n   $ xsh imports x/string\n\n   $ x-string-upper 'hello world'\n   HELLO WORLD\n\n   $ x-string-uuid\n   4be36c77-e507-4eee-9075-1aa259c1613e\n   ```\n\n\n\n### 4.3. Update xsh itself\n\nSee the current xsh version:\n\n```bash\n$ xsh version\n\n0.1.4\n```\n\nList all available xsh versions(tags):\n\n```bash\n$ xsh versions\n\n0.1.0\n0.1.1\n0.1.2\n0.1.3\n0.1.4\n```\n\nUpdate xsh to the latest tagged version:\n\n```bash\n$ xsh upgrade\n```\n\nUpdate xsh to a historical tagged version:\n\n```bash\n$ xsh upgrade -t \u003ctag\u003e\n```\n\n\n\n### 4.4. Get Help\n\nSee the help info of xsh itself:\n\n```bash\n$ xsh help\n```\n\nSee the help info of xsh utilities by LPUR:\n\n```bash\n$ xsh help \u003cLPUR\u003e\n```\n\nSee the specific section of help info of xsh utilities by LPUR:\n\n```bash\n$ xsh help -s \u003cSECTION\u003e \u003cLPUR\u003e\n```\n\nSee the code of xsh utilities by LPUR:\n\n```bash\n$ xsh help -c \u003cLPUR\u003e\n```\n\nList all loaded libraries:\n\n```bash\n$ xsh list\n\nx (0.1.0) =\u003e xsh-lib/core\n```\n\nList utilities by LPUR:\n\n```bash\n$ xsh list \u003cLPUR\u003e\n```\n\nList all utilities of all libraries:\n\n```\n$ xsh list '*'\n```\n\n\n\n## 5. Development\n\n\n\n### 5.1. How to Make Your Own xsh Libraries?\n\nThe directory structure and files of a sample library look like this:\n\n```\nxsh-lib-sample/\n├── functions\n│   └── string\n│       └── lower.sh\n│       └── random.sh\n│       └── upper.sh\n│       └── uuid.sh\n├── scripts\n│   └── log\n│       └── filter.sh\n└── xsh.lib\n```\n\nLet each of your functions be a single `.sh` file, named as the same as the function name, put them under the directory `functions`, you are free to organize the subdirectories, for this sample, they are `string` and `log` that is called `packages`.\n\n\n\n#### 5.1.1. xsh.lib\n\n`xsh.lib` is a config file for the library, `xsh` will read configuration from it.\n\nSupported configurations:\n\n##### name=\u003clib_name\u003e\n* Required: YES\n\n* Description: \u003clib_name\u003e is used as library name.\n\n\n\n#### 5.1.2 Sample code\n\ncat `xsh-lib-sample/xsh.lib`:\n\n```\nname=smpl\n```\n\ncat `xsh-lib-sample/functions/string/upper.sh`:\n\n```bash\n#? Usage:\n#?   @upper STRING ...\n#?\n#? Output:\n#?   Uppercase presentation of STRING.\n#?\n#? Example:\n#?   @upper Foo\n#?   # FOO\n#?\nfunction upper () {\n    echo \"$@\" | tr [a-z] [A-Z]\n}\n```\n\nYou will need to follow the exact comment style to let xsh generate help info.\n\nThe function should be started with the exact syntax:\n\n```\nfunction \u003cname\u003e ()\n```\n\nIt's pretty the same with script files, except that you don't have to define functions inside the script.\n\n\n\n#### 5.1.3. Commit the code and test it\n\nPush the code to a Git repo, for example, GitHub, on branch `master`, then the library is ready for the test.\n\nLoad the sample library `xsh-lib-sample` on GitHub:\n\nNote: Option `-b master` is necessary to tell that you are loading the latest untagged version for testing purposes.\n\n```bash\n$ xsh load -b master \u003cyourusername\u003e/xsh-lib-sample\n```\n\nOr if the Git repo isn't on GitHub, issue:\n\n```\n$ xsh load -s https://yourgitserver.com -b master \u003cyourusername\u003e/xsh-lib-sample\n```\n\nThen can be called as:\n\n```bash\n$ xsh smpl/string/lower\n$ xsh smpl/string/upper\n$ xsh smpl/log/filter\n```\n\n\n\n#### 5.1.4. Publish the library\n\nTo tell the world that the library is ready, you have to make at least one Git tag to publish the library.\n\nTo use [Semantic Versioning](https://semver.org) for the tag name is recommended.\n\nTo make an annotated tag `1.0.0` on the latest commit of branch `master`, issue:\n\n```\n$ git tag -a -m 'v1.0.0' 1.0.0\n```\n\nThen the library is ready.\n\nLoad the published sample library `xsh-lib-sample` on GitHub:\n\n```bash\n$ xsh load \u003cyourusername\u003e/xsh-lib-sample\n```\n\n\n\n#### 5.1.5. Create library with template\n\nUsing the GitHub template repository [xsh-lib/template](https://github.com/xsh-lib/template) is the simplest way to create a new empty xsh library.\n\n\n\n#### 5.1.6. xsh library INIT files\n\nxsh library INIT files are used to initialize the library environment.\n\nThe INIT file is a script file named `__init__.sh` and placed at any level under the library `functions` directory.\n\nThe INIT file is sourced while importing any function utility, right before the function utility was sourced.\n\nThe source of the INIT file won't happen again on the subsequence calls of the function utility until it is imported again, except a `runtime` decorator is used on the INIT file.\n\n\n\n#### 5.1.7. xsh library decorators\n\nDecorators are used to add metadata to the functions, and init files in xsh libraries.\nIt should start with `@` and be placed at the comment block of the function, or INIT file, right before the function, or INIT file definition.\n\n\n\n##### 5.1.7.1. Decorators for functions\n\nThe decorators are used to add metadata to the functions in xsh libraries.\n\n\n\n###### 5.1.7.1.1. Decorator `xsh`\n\nThe `xsh` decorator is used to call the xsh framework functions.\n\n\n\n###### 5.1.7.1.2. Decorator `subshell`\n\nThe `subshell` decorator is used to create a subshell to isolate the environment of the function from the caller's environment.\n\n\n\n##### 5.1.7.2. Decorators for INIT files\n\nThe decorators are used to add metadata to the INIT files in xsh libraries.\n\n\n###### 5.1.7.2.1. Decorator `static`\n\nThe `static` decorator is used to make the INIT file to be sourced only once on the first call of the function utility, and won't be sourced again on the subsequence calls of the function utility.\n\nThis is default behavior if no decorator is used on the INIT file.\n\n\n\n###### 5.1.7.2.2. Decorator `runtime`\n\nThe `runtime` decorator is used to make the INIT file to be sourced on every call of the function utility, even it is already sourced before.\n\n\n\n##### 5.1.7.3. Examples of using decorators in xsh libraries\n\n1. Clean up on function return\n\n```bash\n#? @xsh imports /trap/return\n#? @subshell\n#?\nfunction foo () {\n    x-trap-return -f \"${FUNCNAME[0]}\" \"echo 'clean up on this function returns'\"\n    echo \"foo\"\n}\n```\n\nThe equvalent code:\n```bash\nfunction foo () {\n    (\n    function __foo__ () {\n        xsh imports /trap/return\n        x-trap-return -f \"${FUNCNAME[0]}\" \"echo 'clean up on this function returns'\"\n        echo \"foo\"\n    }\n    __foo__ \"$@\"\n    )\n}\n```\n\nsee details by `xsh help /trap/return`.\n\n2. Clean up on function return or any error occurs\n\n```bash\n#? @xsh imports /trap/return\n#? @xsh /trap/err -rE\n#? @subshell\n#?\nfunction foo () {\n    x-trap-return -f \"${FUNCNAME[0]}\" \"echo 'clean up on this function returns or any error occurs'\"\n    echo \"foo\"\n}\n```\n\nsee details by `xsh help /trap/err`.\n\n\n\n### 5.2. Debugging (Debug Mode)\n\nWith the debug mode enabled, the shell options: `-vx` is set for the debugging utilities. The debug mode is available only for the commands started with `xsh`.\n\nEnable the debug mode by setting an environment variable: `XSH_DEBUG` before the command `xsh`.\n\nValues for XSH_DEBUG:\n```\n1     : Enable the debug mode for whatever the LPUE input by `xsh`.\n        e.g: XSH_DEBUG=1 xsh /string/upper foo\n\u003cLPUR\u003e: Enabled the debug mode for the LPUE input by `xsh` if the LPUE equals to or matches the \u003cLPUR\u003e set by XSH_DEBUG.\n        e.g: XSH_DEBUG=/string xsh /string/upper foo\n        e.g: XSH_DEBUG=/string/pipe/upper xsh /string/upper foo\n```\n\nThe debug mode applies to the following commands and internal functions:\n* calls\n* call, exec\n\nThe debug mode is for debugging xsh libraries.\nFor the general debugging purpose, use `xsh debug`, see `xsh help debug`.\n\n`xsh debug [-1 OPTION] [-0 OPTION] [...] \u003cFUNCTION | SCRIPT\u003e`\n\nIt provides a consistent way to debug functions and scripts without having to manually switch the shell options on and off, especially with functions, the syntax `bash -x script.sh` is out of hands. Although you may use the subprocess syntax `(set -x; foo_func)` to avoid messing the current process up, but subprocess has its own side effects.\n\n\n\n### 5.3. Development at Local (Dev Mode)\n\nThe dev mode is for developers to develop xsh libraries.\nWith the dev mode enabled, the utilities from the development library will be used rather than those from the normal library.\nThe dev mode is available only for the commands started with `xsh`.\n\nBefore using the dev mode, you need to create symbol links for the libraries that need to use dev mode, put the symbol links in the directory `~/.xsh/lib-dev`, and point them to your development workspaces.\nThis can be done with the command: `xsh lib-dev-manager link ...`, and be undone with the command `xsh lib-dev-manager unlink ...`.\n\nExample:\n\n```bash\n$ xsh lib-dev-manager link xsh-lib/core ~/projects\n$ xsh lib-dev-manager link xsh-lib/aws ~/projects\n```\n\nAfter the link, the development libraries look like:\n\n```bash\n$ ls -l ~/.xsh/lib-dev\ntotal 0\nlrwxr-xr-x  1 alex  staff  32 Sep  4 16:36 aws -\u003e /Users/alex/projects/xsh-lib/aws\nlrwxr-xr-x  1 alex  staff  33 Sep  4 16:36 x -\u003e /Users/alex/projects/xsh-lib/core\n```\n\nThen the dev mode is ready to use.\nEnable the dev mode by setting an environment variable: `XSH_DEV` before the command `xsh`.\n\nValues for XSH_DEV:\n```\n1     : Enable the dev mode for whatever the LPUE or LPUR input by `xsh`.\n        e.g: XSH_DEV=1 xsh /string/upper foo\n             XSH_DEV=1 xsh import /string\n             XSH_DEV=1 xsh list\n\n\u003cLPUR\u003e: Enabled the dev mode for the LPUE or LPUR input by `xsh` if the LPUE/LPUR equals to or matches the \u003cLPUR\u003e set by XSH_DEV.\n        e.g: XSH_DEV=/string xsh import /string\n        e.g: XSH_DEV=/string xsh help /string/upper\n        e.g: XSH_DEV=/string/pipe/upper xsh /string/upper foo\n        Be noted, the following usage won't work as expected:\n        e.g: XSH_DEV=/string xsh import /\n```\n\nThe dev mode applies to the following commands and internal functions:\n* calls, imports, unimports, list, help\n* call, import, unimport, lib_list, help_lib\n\n\n\n### 5.4. Development of xsh\n\n* IDE: [PyCharm](https://www.jetbrains.com/pycharm/) \u0026 [Aquamacs](http://aquamacs.org)\n* Code static analysis: [ShellCheck](https://www.shellcheck.net)\n* Code static analysis integration: [CodeFactor](https://www.codefactor.io/dashboard)\n* Code testing framework: [ShellSpec](https://shellspec.info)\n* Code coverage: [Kcov](https://github.com/SimonKagstrom/kcov)\n* Code coverage analysis: [CodeCov](https://codecov.io)\n* Code hosting: GitHub\n* CI hosting: [Travis](https://travis-ci.com)\n\nMost of them are free, or free to OSS projects. Many thanks to whoever contributes to them.\n\n\n\n## 6. Where to find xsh Libraries\n\n1. Check out the repositories under [official xsh library site](https://github.com/xsh-lib).\n\n1. Search GitHub repositories with the keyword `xsh-lib-`.\n\n\n\n## 7. TODO\n\n* Dependency\n\n* Library registration\n\n* Document generation\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexzhangs%2Fxsh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexzhangs%2Fxsh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexzhangs%2Fxsh/lists"}