{"id":17383609,"url":"https://github.com/mklement0/shall","last_synced_at":"2025-10-10T16:36:21.881Z","repository":{"id":25016070,"uuid":"28435323","full_name":"mklement0/shall","owner":"mklement0","description":"A CLI and REPL for invoking shell scripts or commands with multiple POSIX-like shells for portability testing.","archived":false,"fork":false,"pushed_at":"2022-12-27T13:52:48.000Z","size":93,"stargazers_count":46,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-05T07:29:41.532Z","etag":null,"topics":["cli","cross-platform","posix-sh","shell","testing","unix-cli"],"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/mklement0.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-24T04:59:53.000Z","updated_at":"2025-07-03T23:40:08.000Z","dependencies_parsed_at":"2023-01-14T01:59:09.940Z","dependency_job_id":null,"html_url":"https://github.com/mklement0/shall","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/mklement0/shall","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Fshall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Fshall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Fshall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Fshall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mklement0","download_url":"https://codeload.github.com/mklement0/shall/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Fshall/sbom","scorecard":{"id":652617,"data":{"date":"2025-08-11","repo":{"name":"github.com/mklement0/shall","commit":"21e66dd0725e6bc6f617df3c480906cb555d9a1e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":["Info: Possibly incomplete results: error parsing shell code: reached ) without matching $(( with )): bin/shall:0"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-21T13:51:33.461Z","repository_id":25016070,"created_at":"2025-08-21T13:51:33.461Z","updated_at":"2025-08-21T13:51:33.461Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279004690,"owners_count":26083750,"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","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"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":["cli","cross-platform","posix-sh","shell","testing","unix-cli"],"created_at":"2024-10-16T07:43:14.696Z","updated_at":"2025-10-10T16:36:21.861Z","avatar_url":"https://github.com/mklement0.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm version](https://img.shields.io/npm/v/shall.svg)](https://npmjs.com/package/shall) [![license](https://img.shields.io/npm/l/shall.svg)](https://github.com/mklement0/shall/blob/master/LICENSE.md)\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n**Contents**\n\n- [shall \u0026mdash; introduction](#shall-\u0026mdash-introduction)\n- [Examples](#examples)\n- [Installation](#installation)\n  - [Installation from the npm registry](#installation-from-the-npm-registry)\n  - [Manual installation](#manual-installation)\n- [Usage](#usage)\n- [License](#license)\n  - [Acknowledgements](#acknowledgements)\n  - [npm dependencies](#npm-dependencies)\n- [Changelog](#changelog)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n# shall \u0026mdash; introduction\n\n`shall` is a Unix CLI and REPL for invoking shell scripts or commands with\nmultiple POSIX-like shells for portability testing.\n\n**`shall`** (for ***sh***ell with ***all*** (POSIX-like) shells) offers a\nconvenient way of running a given shell script or shell command with a default\nset or specifiable set of POSIX-like shells, so as to facilitate testing of\nportable (POSIX-compliant, cross-shell) shell code.\n\nBy default, the following shells are targeted, if installed: **sh, dash, bash, zsh, ksh**\n\nAdditionally, you can use `shall`:\n\n* as a REPL, with `-i`.\n* in a script's shebang line.\n\nEach shell's execution is automatically timed to allow performance comparisons.\n\nThe syntax is modeled on that of the underlying shells.\n\nSee the examples below, concise [usage information](#usage) further below,\nor read the [manual](doc/shall.md).\n\n# Examples\n\n```sh\n\n# Echo the name of each executing shell; sample output included.\n$ shall -c 'echo \"Hello from $0.\"'\n```\n![Hello example - sample output](doc/images/example-output-hello.png)\n\n\n```sh\n\n# Pass a script to all shells via stdin, plus an argument on the command line.\necho 'echo \"Passed to $0: $1\"' | shall -s one\n\n# Execute script 'foo-script' with argument 'bar' in all shells.\nshall foo-script bar\n\n# Print the type of the 'which' command in Bash and Zsh.\nshall -w bash,zsh -c 'type which'\n\n# Enter a REPL that evaluates commands in both Bash and Dash.\nSHELLS=bash,dash shall -i\n\n```\n\n# Installation\n\n**Supported platforms**\n\n* When installing from the [**npm registry**](https://www.npmjs.com): all **Unix-like** platforms supported by [Node.js](http://nodejs.org/) with [**Bash**](http://www.gnu.org/software/bash/) installed.\n* When installing **manually**: any **Unix-like** platform with **Bash** installed.\n\n## Installation from the npm registry\n\n\u003csup\u003eNote: Even if you don't use Node.js, its package manager, `npm`, works across platforms and is easy to install; try [`curl -L http://git.io/n-install | bash`](https://github.com/mklement0/n-install)\u003c/sup\u003e\n\nWith [Node.js](http://nodejs.org/) or [io.js](https://iojs.org/) installed, install [the package](https://www.npmjs.com/package/shall) as follows:\n\n    [sudo] npm install shall -g\n\n**Note**:\n\n* Whether you need `sudo` depends on how you installed Node.js / io.js and whether you've [changed permissions later](https://docs.npmjs.com/getting-started/fixing-npm-permissions); if you get an `EACCES` error, try again with `sudo`.\n* The `-g` ensures [_global_ installation](https://docs.npmjs.com/getting-started/installing-npm-packages-globally) and is needed to put `shall` in your system's `$PATH`.\n\n## Manual installation\n\n* Download [the CLI](https://raw.githubusercontent.com/mklement0/shall/stable/bin/shall) as `shall`.\n* Make it executable with `chmod +x shall`.\n* Move it or symlink it to a folder in your `$PATH`, such as `/usr/local/bin` (OSX) or `/usr/bin` (Linux).\n\n# Usage\n\nFind concise usage information below; for complete documentation, read the [manual online](doc/shall.md), or, once installed, run `man shall` (`shall --man` if installed manually).\n\n\u003c!-- DO NOT EDIT THE FENCED CODE BLOCK and RETAIN THIS COMMENT: The fenced code block below is updated by `make update-readme/release` with CLI usage information. --\u003e\n\n```nohighlight\n$ shall --help\n\n\nCross-POSIX-compatible-shell testing:\n\nRun a script file:\n\n    shall [-w \u003cshellA\u003e,...] [-q|-Q] [-p \u003copts\u003e]     \u003cscript\u003e [\u003carg\u003e...]\n\nExecute a command string:\n\n    shall [-w \u003cshellA\u003e,...] [-q|-Q] [-p \u003copts\u003e]  -c \u003ccmd\u003e    [\u003carg0\u003e \u003carg\u003e...]\n\nExecute commands specified via stdin:\n\n    shall [-w \u003cshellA\u003e,...] [-q|-Q] [-p \u003copts\u003e] [-s           \u003carg\u003e...]\n\nStart a REPL (run commands interactively):\n\n    shall [-w \u003cshellA\u003e,...]  -i\n\nDefault shells targeted are sh, and, if installed, dash, bash, zsh, ksh.  \nOverride with -w or environment variable SHELLS, using a comma-separated  \nlist without spaces; e.g., -w bash,ksh,zsh or SHELLS=bash,ksh,zsh.\n\n-q, -Q quiets stdout, stdout + stderr from the script / commands invoked.  \n-p passes options through to the target shells.\n\nStandard options: --help, --man, --version, --home\n```\n\n\u003c!-- DO NOT EDIT THE NEXT CHAPTER and RETAIN THIS COMMENT: The next chapter is updated by `make update-readme/release` with the contents of 'LICENSE.md'. ALSO, LEAVE AT LEAST 1 BLANK LINE AFTER THIS COMMENT. --\u003e\n\n# License\n\nCopyright (c) 2014-2015 Michael Klement, released under the [MIT license](https://spdx.org/licenses/MIT#licenseText).\n\n## Acknowledgements\n\nThis project gratefully depends on the following open-source components, according to the terms of their respective licenses.\n\n[npm](https://www.npmjs.com/) dependencies below have optional suffixes denoting the type of dependency; the absence of a suffix denotes a required run-time dependency: `(D)` denotes a development-time-only dependency, `(O)` an optional dependency, and `(P)` a peer dependency.\n\n\u003c!-- DO NOT EDIT THE NEXT CHAPTER and RETAIN THIS COMMENT: The next chapter is updated by `make update-readme/release` with the dependencies from 'package.json'. ALSO, LEAVE AT LEAST 1 BLANK LINE AFTER THIS COMMENT. --\u003e\n\n## npm dependencies\n\n* [doctoc (D)](https://github.com/thlorenz/doctoc)\n* [json (D)](https://github.com/trentm/json)\n* [marked-man (D)](https://github.com/kapouer/marked-man#readme)\n* [replace (D)](https://github.com/harthur/replace)\n* [semver (D)](https://github.com/isaacs/node-semver)\n* [urchin (D)](https://git.sdf.org/tlevine/urchin)\n\n\u003c!-- DO NOT EDIT THE NEXT CHAPTER and RETAIN THIS COMMENT: The next chapter is updated by `make update-readme/release` with the contents of 'CHANGELOG.md'. ALSO, LEAVE AT LEAST 1 BLANK LINE AFTER THIS COMMENT. --\u003e\n\n# Changelog\n\nVersioning complies with [semantic versioning (semver)](http://semver.org/).\n\n\u003c!-- NOTE: An entry template is automatically added each time `make version` is called. Fill in changes afterwards. --\u003e\n\n* **[v0.2.8](https://github.com/mklement0/shall/compare/v0.2.7...v0.2.8)** (2015-10-23):\n  * [doc] `README.md` examples still contained obsolete `-l` switch.\n  * [dev] Improved robustness of internal `rreadlink()` function.\n\n* **[v0.2.7](https://github.com/mklement0/shall/compare/v0.2.6...v0.2.7)** (2015-09-20):\n  * [dev] Confusing changelog typos fixed.\n  * [dev] Removed post-install command that verifies presence of Bash, because\n    `npm` always _prints_ the command during installation, which can be confusing.  \n\n* **[v0.2.6](https://github.com/mklement0/shall/compare/v0.2.5...v0.2.6)** (2015-09-19):\n  * [doc] `shall` now has a man page (if manually installed, use `shall --man`);\n          `shall -h` now just prints concise usage information.\n\n* **[v0.2.5](https://github.com/mklement0/shall/compare/v0.2.4...v0.2.5)** (2015-09-15):\n  * [dev] Makefile improvements; various other behind-the-scenes tweaks.\n\n* **[v0.2.4](https://github.com/mklement0/shall/compare/v0.2.3...v0.2.4)** (2015-07-08):\n  * [fix] Pass-through option-arguments with embedded spaces are now handled correctly; process substitution replaced with alternative so as to improve FreeBSD compatibility.\n  * [doc] Read-me improved, notably: manual-installation instructions added, TOC added.\n\n* **[v0.2.3](https://github.com/mklement0/shall/compare/v0.2.2...v0.2.3)** (2015-06-26):\n  * [doc] Read-me: npm badge changed to [shields.io](http://shields.io); license badge added; typo fixed.\n  * [dev] To-do added; Makefile updated.\n\n* **v0.2.2** (2015-05-31):\n  * [doc] [npm registry badge](https://badge.fury.io) added\n\n* **v0.2.1** (2015-05-27):\n  * [fix] Options passed through with -p are no longer ignored on Linux.\n  * [fix] Removed extraneous status output.\n\n* **v0.2.0** (2015-05-24):\n  * [new] New -p option allows passing additional options through to the shells invoked; e.g.: -p '-e'\n  * [deprecated] -l option for specifying shells to target renamed to -w to avoid confusion with shells' native -l version (login shells); -l will continue to work. \n  * [robustness] Exit codes relating to shall's *own* failures changed to: 126 (incorrect arguments) and 127 (unexpected failure), chosen so as to avoid clashes with exit codes produced during normal operation and termination by signal.\n\n* **v0.1.7** (2015-02-11):\n  * [doc] improved description in package.json\n\n* **v0.1.6** (2015-02-11):\n  * [fix] When using the default target shells, only those actually installed should be targeted.\n\n* **v0.1.5** (2015-02-11):\n  * [install] warning added, if bash not found\n  * [dev] bash-presence test improved\n  * [dev] Makefile improvements\n\n* **v0.1.4** (2015-02-11):\n  * [dev] testing no longer requires the CLI to be in the path\n  * [dev] bash-presence test added\n  * [dev] Makefile improvements\n  * [doc] read-me improvements (examples)\n\n* **v0.1.3** (2015-01-28):\n  * [doc] read-me typo corrected\n  * [dev] Makefile improvements\n\n* **v0.1.2** (2015-01-27):\n  * [fix] -q option no longer masks failures\n  * [doc] CLI help and read-me updates\n  * [dev] Urchin-based tests added\n\n* **v0.1.1** (2014-12-23):\n  * [doc] read-me and CLI help fixes\n\n* **v0.1.0** (2014-12-23):\n  * Initial release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmklement0%2Fshall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmklement0%2Fshall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmklement0%2Fshall/lists"}