{"id":18327367,"url":"https://github.com/seungh06/node-sh","last_synced_at":"2025-04-06T01:32:03.278Z","repository":{"id":45406101,"uuid":"492250155","full_name":"seungh06/node-sh","owner":"seungh06","description":"Portable bash command implementation and os shell command execution for node.js","archived":false,"fork":false,"pushed_at":"2023-04-03T11:03:00.000Z","size":174,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-21T14:48:47.184Z","etag":null,"topics":["bash","binary","executable","nodejs","process","shell","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/seungh06.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":"2022-05-14T15:11:35.000Z","updated_at":"2024-12-01T08:56:16.000Z","dependencies_parsed_at":"2024-11-05T19:10:46.103Z","dependency_job_id":null,"html_url":"https://github.com/seungh06/node-sh","commit_stats":{"total_commits":63,"total_committers":2,"mean_commits":31.5,"dds":"0.47619047619047616","last_synced_commit":"ae09288fd6e609cdfbb3c7070e2bf54ff25d3b55"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seungh06%2Fnode-sh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seungh06%2Fnode-sh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seungh06%2Fnode-sh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seungh06%2Fnode-sh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seungh06","download_url":"https://codeload.github.com/seungh06/node-sh/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247423473,"owners_count":20936621,"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","binary","executable","nodejs","process","shell","typescript"],"created_at":"2024-11-05T19:10:41.671Z","updated_at":"2025-04-06T01:32:02.234Z","avatar_url":"https://github.com/seungh06.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![banner](https://user-images.githubusercontent.com/41784860/168438812-90eed635-2fe3-477e-8a25-6527036bffce.png)\n\n[![nodejs](https://img.shields.io/badge/NodeJS-339933?style=for-the-badge\u0026logo=Node.js\u0026logoColor=fff)](https://nodejs.org/)\n[![typescript](https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge\u0026logo=TypeScript\u0026logoColor=fff)](https://www.typescriptlang.org/)\n[![license](https://img.shields.io/badge/license-MIT-9999FF?style=for-the-badge)](/LICENSE)\n\nNode-sh is a bash command implementation and os shell command execution for node.js that runs on mac os, linux and windows. It makes you easier to execute your os shell commands, implement bash commands and functionalize it.\n\n### 🕹 Install\n```bash\n $ yarn add node-sh@npm:@seung_h/node-sh\n $ npm install node-sh@npm:@seung_h/node-sh\n```\n\n## 🔥 Features\n- TypeScript based, zero dependencies. 📦\n- Simple command execution with user environment.\n- **26** bash commands implemented.\n- Each command supports type-based JavaScript API and pipe commands.\n- Provides details about exceptions in user command with rendered code. \n\n## 📌 Import\n```typescript\n import 'node-sh' // $.commands\n import bash from 'node-sh' // bash.commands (named)\n```\n\n## 📝 Usage\n```typescript\n import 'node-sh'\n \n const version = $.cat `package.json`.grep `version`\n \n if(version.includes('dev') || process.env.dev) {\n     $.cp `-r bin asm`\n     $.chmod `--reference bin/exec asm/*`\n     $.rm `-rf bin`\n }\n \n const bash = $.which `bash`\n $.set `shell=${ bash }` //$.env.shell = bash.stdout\n $.echo `execution environment: $shell`\n \n $.chmod `u+x build.sh`\n $ `build.sh` // exec\n```\n\n## 🔐 Command Reference\nAll commands run synchronously and return `UnixExtension` class (except void functions) that can use JavaScript API, redirection and pipe functions. Interpreter accept glob characters and change `$variable` to environment variable, `${...}` expression to escape and quotes. etc.\n\n### ``$ `command` ``\nExecutes a command directly in the shell specified by the `shell` variable, using [child process](https://nodejs.org/api/child_process.html) module.\n```typescript\n const exec = $ `ls -al | grep node-sh` // UnixExtension\u003cstring\u003e\n```\n\n### ``.redirect `OPERATOR FILE` ``\nCreate stdout redirection of executed commands. use `\u003e` operator to overwrite and `\u003e\u003e` operator to insert.\n```typescript\n $.cat `-n build.sh`.redirect `\u003e\u003e output.txt`\n```\n\n\u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003e✏️ Show All Command References\u003c/b\u003e\u003c/summary\u003e\n\n### ``$.cat `[OPTION]... [FILE]...` ``\nReturn the contents of a given FILE or concatenated FILE(s) to standard output.\n\n - `-n, --number` : number all output lines.\n - `-E, --show-ends` : display `$` at end of each line.\n - `-T, --show-tabs` : display `TAB` characters as `^I`\n\n```typescript\n const cat = $.cat `-nE src/*.ts` // UnixExtension\u003cstring\u003e\n```\n\n### ``$.cd `[DIR]` ``\nChange the current directory to `DIR`. Change to the previous directory using the `-` or `$OLDPWD` variable. If no stdin is supplied or `-`, change to `HOME` directory.\n```typescript\n $.cd `src`\n $.cd `$OLDPWD/dist`\n```\n\n### ``$.chmod `[OPTION]... MODE[RFILE] FILE...` ``\nChange the mode of each FILE to `MODE`. If `reference` option is supplied, change the mode of each FILE to that of `RFILE`.\n\n - `-c, --changes` : report only when a change is made.\n - `--reference=RFILE` : use `RFILE`'s mode instead of `MODE` values.\n - `-R, --recursive` : change files and directories recursively.\n\n```typescript\n $.chmod `755 build.sh`\n $.chmod `-R a=rwx dist`\n $.chmod `--reference test.sh build.sh`\n```\n\n### ``$.cp `[OPTION]... SOURCE... DEST[DIRECTORY]` ``\nCopy `SOURCE` to `DEST`, or multiple `SOURCE(s)` to `DIRECTORY`.\n\n - `-b, --backup` : make a backup of each existing destination file.\n - `-S, --suffix=SUFFIX` : override the usual backup suffix (`~`).\n - `-l, --dereference` : always follow symbolic links in `SOURCE`.\n - `-p, --no-dereference` : never follow symbolic links in `SOURCE`.\n - `-r, -R, --recursive` : copy directories recursively.\n - `-u, --update` : copy only when the `SOURCE` file is newer than the destination file or when the destination file is missing.\n \n```typescript\n $.cp `test.ts src`\n $.cp `test.ts test1.ts src`\n $.cp `-rbS BACKUP_ build src` // backup suffix = BACKUP_\n```\n \n### ``$.dirs `[+N] [N]` ``\nDisplay the list of currently remembered directories. Add the directory stack using the `pushd` command and back up with the `popd` command.\n \n - `-c` : clear the directory stack by deleting all of the elements.\n  \n Arguments:\n - `+N` : Displays the `N`th entry counting from the left of the list when invoked without options, starting with zero.\n - `N` : Displays the `N`th entry counting from the right of the list when invoked without options, starting with zero.\n\n```typescript\n const dirs = $.dirs `` // UnixExtension\u003cstring[]\u003e \n \n $.dirs `-c`\n $.dirs `+3`\n```\n\n### ``$.echo `[OPTION]... [STRING]...` ``\nEcho the STRING(s) to standard output and print it.\n \n - `-n` : do not output the trailing newline.\n \n```typescript\n const echo = $.echo `Hello World!` // UnixExtension\u003cstring\u003e\n $.echo `Print`\n```\n\n### ``$.grep  `[OPTION]... PATTERN [FILE]...` ``\nSearch for `PATTERN(REGEX)` in each `FILE`.\n\n - `-i, --ignore-case` : ignore case distinctions in patterns and data.\n - `-v, --invert-match` : select non-matching lines.\n - `-n, --line-number` : print line number with output lines.\n - `-H, --with-filename` : print file name with output lines.\n - `-r, --recursive` : read all files under each directory, recursively.\n - `-l, --files-with-matches` : print only names of `FILE`s with selected lines.\n \n``` typescript\n const grep = $.grep `-i ^import src/*.ts` // UnixExtension\u003cstring[]\u003e\n```\n\n### ``$.head  `[OPTION]... [FILE]...` ``\nPrint the first `10` lines of each `FILE` to standard output. If multiple files are supplied, prepend each with a header indicating the file name.\n\n - `-c, --bytes=NUM` : print the first `NUM` bytes of each file\n - `-n, --lines=NUM` : print the first `NUM` lines instead of the first `10`.\n - `-q, --quiet, --silent` : never print headers giving file names.\n \n```typescript\n const head = $.head `-n 15 src/test.ts` // UnixExtension\u003cstring\u003e\n \n $.head `-c 100 src/test.ts`\n $.head `-q src/*.ts`\n```\n\n### ``$.ln  `[OPTION]... SOURCE DEST` ``\nBy default, create hard link from `SOURCE` to `DEST`. If `-s` or `--symbolic` option is supplied, create symbolic link.\n\n - `-b, --backup` : make a backup of each existing destination file.\n - `-f, --force` : remove existing destination files.\n - `-s, --symbolic` : make symbolic links instead of hard links.\n - `-S, --suffix=SUFFIX` : override the usual backup suffix(`~`).\n \n```typescript\n $.ln `file link`\n $.ln `-bS BACKUP_ file exist` // backup suffix = BACKUP_\n```\n\n### ``$.ls  `[OPTION]... [FILE]...` ``\nList information about the `FILE(s)`. If `FILE` is not supplied, list information about the current directory.\n\n - `-a, --all` : do not ignore entries starting with `.`.\n - `-A, --almost-all` : do not list implied `.` and `..`.\n - `-d, --directory` : list directories themselves, not their contents.\n - `-l` : use a long listing format.\n - `-L, --dereference` : show information for the file the link references rather than for the link itself.\n - `-r, --reverse` : reverse order while sorting.\n - `-R, --recursive` : list subdirectories recursively.\n \n```typescript\n const ls = $.ls `-al`\n \n $.ls `-R src dist`\n $.ls `-l src/**/*.ts`\n```\n \n### ``$.mkdir  `[OPTION]... DIRECTORY...` ``\nCreate the `DIRECTORY(ies)`, if they do not already exist.\n\n - `-m, --mode=MODE` : set file mode (must be octal - unmask).\n - `-p, --parents` : no error if existing, make parent directories as needed.\n\n```typescript\n $.mkdir `test test1`\n $.mkdir `-m 777 test`\n $.mkdir `-p test/test1` // if 'test' is not exist, make it.\n```\n\n### ``$.mv  `[OPTION]... SOURCE... DEST[DIRECTORY]` ``\nRename `SOURCE` to `DEST`, or move `SOURCE(s)` to `DIRECTORY`.\n \n - `-b, --backup` : make a backup of each existing destination file.\n - `-S, --suffix=SUFFIX` : override the usual backup suffix(`~`).\n \n```typescript\n $.mv `file file_renamed`\n $.mv `file file1 dir` // rename to 'dir/file', 'dir/file1'.\n```\n\n### ``$.popd `[-n] [+N | N]` ``\nRemove directories from stack. If no arguments are supplied, remove the top directory from the stack, and changes to the new top directory.\n\n - `-n` : Suppresses the normal change of directory when removing directories from the stack, so only the stack is manipulated.\n \nArguments:\n - `+N` : Removes the `N`th entry counting from the left of the list, starting with zero.\n - `N` : Removes the `N`th entry counting from the right of the list, starting with zero.\n \n```typescript\n const popd = $.popd `` // UnixExtension\u003cstring[]\u003e - directory stack.\n $.popd `-n`\n $.popd `+3`\n```\n\n### ``$.pushd `[-n] [+N | N | DIR]` ``\nAdd directories to stack. If no arguments are supplied, exchanges the top two directories.\n\n - `-n` : Suppresses the normal change of directory when adding directories to the stack, so only the stack is manipulated.\n \nArguments:\n - `+N` : Rotates the stack so that the `N`th directory counting from the left of the list, starting with zero is at the top.\n - `N` : Rotates the stack so that the `N`th directory counting from the right of the list, starting with zero is at the top.\n - `DIR` : Adds `DIR` to the directory stack at the top, making it the new current working directory.\n \n```typescript\n const pushd = $.pushd `` // UnixExtension\u003cstring[]\u003e - directory stack.\n $.pushd `-n hello`\n $.pushd `dir`\n```\n\n### ``$.pwd ` ` ``\nPrint the name of the current working directory.\n\n```typescript\n const pwd = $.pwd `` // UnixExtension\u003cstring\u003e\n```\n\n### ``$.rm `[OPTION]... [FILE]...` ``\nRemove (unlink) the `FILE(s)`.\n\n - `-f, --force` : ignore nonexistent files and arguments, never prompt.\n - `-r, --recursive` : remove directories and their contents recursively.\n \n```typescript\n $.rm `file`\n $.rm `file file1 file2`\n $.rm `-rf dir`\n```\n\n### ``$.rmdir `[OPTION]... DIRECTORY...` ``\nRemove the `DIRECTORY(ies)`, if they are empty.\n \n - `-p, --parents` : remove `DIRECTORY` and its ancestors; `rmdir -p a/b/c` -\u003e `rmdir a/b/c a/b a`\n \n```typescript\n $.rmdir `dir`\n $.rmdir `-p parent/dir`\n```\n\n### ``$.set `[-fvC]` ``\nSet or unset, change the value of shell variables and attributes. If no arguments or options are supplied, display the names and values of shell variables.\nUsing `+` rather than `-` causes these flags to be turned off.\n\n - `-f` : Disable file name generation (globbing).\n - `-v` : Print shell input lines as they are read(verbose).\n - `-C` : If set, disallow existing regular files to be overwritten by redirection(`\u003e`) of output.\n \n```typescript\n const set = $.set ``\n \n $.set `-fC`\n $.set `+f`\n $.set `var1=value`\n```\n\n### ``$.sleep  `NUMBER[SUFFIX]` ``\nPause for `NUMBER` seconds. `SUFFIX` may be 's' for seconds (default), 'm' for minutes, 'h' for hours or 'd' for days.\n\n```typescript\n $.sleep `5`  // 5 seconds\n $.sleep `5m` // 5 minutes\n```\n\n### ``$.sort  `[OPTION]... [FILE]...` ``\nWrite sorted concatenation of all `FILE(s)` to standard output.\n \n - `-f, --ignore-case` : fold lower case to upper case characters.\n - `-n, --numeric-sort` : compare according to string numerical value.\n - `-r, --reverse` : reverse the result of comparisons.\n \n```typescript\n const sort = $.sort `-f file` // UnixExtension\u003cstring\u003e\n $.sort `-r *.ts file`\n```\n\n### ``$.tail  `[OPTION]... [FILE]...` ``\nPrint the last `10` lines of each `FILE` to standard output. If multiple files are supplied, prepend each with a header indicating the file name.\n\n - `-c, --bytes=NUM` : output the last `NUM` bytes; or use `+NUM` to output starting with byte `NUM` of each file.\n - `-n, --lines=NUM` :  output the last `NUM` lines, instead of the last `10`; or use `+NUM` to output starting with line `NUM`.\n - `-q, --quiet, --silent` : never print headers giving file names.\n \n```typescript\n const tail = $.tail `-n 15 src/test.ts` // UnixExtension\u003cstring\u003e\n \n $.tail `-n +15 src/test.ts`\n $.tail `*.ts files`\n```\n \n### ``$.touch  `[OPTION]... [FILE]...` ``\nUpdate the access and modification times of each `FILE` to the current time. A `FILE` argument that does not exist is created empty unless `-c` option is supplied.\n\n - `-a` : change only the access time.\n - `-c, --no-create` : do not create any files.\n - `-d, --date=STRING` : parse `STRING` and use it instead of current time.\n - `-m` : change only the modification time.\n - `-r, --reference=RFILE` : use this `RFILE`'s times instead of current time.\n \n``` typescript\n $.touch `not_exist.js`     // create 'not_exist.js'\n $.touch `exist.js`         // change access and modification times.\n $.touch `-r file exist.js` // change times of 'exist.js' to 'file's time.\n $.touch `-d 1234-03-21 exist.js` // change times of 'exist.js' to Mar 21, 1234\n```\n\n### ``$.uniq  `[OPTION]... [INPUT [OUTPUT]]` ``\nFilter adjacent matching lines from `INPUT`, writing to `OUTPUT` or standard output.\n\n - `-c, --count` : prefix lines by the number of occurrences.\n - `-d, --repeated` : only print duplicate lines, one for each group.\n - `-i, --ignore-case` : ignore differences in case when comparing.\n \n```typescript\n const uniq = $.uniq `-c file`\n \n $.uniq `file output` // write to 'output'.\n```\n\n### ``$.unset  `name...` ``\nEach environment variable specified by `name` shall be unset.\n\n``` typescript\n $.set `user=Test pass=1234` \n $.unset `user pass`\n```\n\n### ``$.which  `[OPTION]...  PROGRAM` ``\nSearch an executable or script in the directories listed in the environment variable PATH and print full path to standard output.\n\n - `-a, --all` : Print all matching executables in PATH, not just the first.\n \n```typescript\n const which = $.which `git` // UnixExtension\u003cstring\u003e\n $.which `-a node`\n```\n\n### ``$.whoami ` ` ``\nPrint the user name associated with the current effective user ID.\n```typescript\n const user = $.whoami `` // UnixExtension\u003cstring\u003e\n```\n\u003c/details\u003e\n\n## 📐 Environment Variable\nVariables in default structures are used only in the `exec` command. User can set the variable using `set` command or $.env.`name`. All commands change the `$variable` syntax to the value of it.\n\n**Default Environments**\n```typescript\n $.env: {\n     verbose    : boolean           = false\n     prefix     : string            = ''\n     shell      : string | boolean  = true\n     max_buffer : number            = 200 * 1024 * 1024\n } // default structures\n \n $.env.noglob    : boolean = undefined\n $.env.noclobber : boolean = undefined\n $.env.OLDPWD    : string  = undefined\n ...\n```\n**User Environments**\n```typescript\n import 'node-sh'\n \n $.set `name=Jack`      // $.env.name = 'seungh'\n $.echo `Hello, $name`  // Hello, seungh\n```\n\n##  🛠  Exceptions\nNode-sh provides detail of the exceptions that occurred in user commands or internal and suggests solutions for them.\n\n\n![exception](https://user-images.githubusercontent.com/41784860/177758975-93b8b637-8906-457d-9424-354428ffbc82.png)\n\n## 📋 License\nDistributed under the MIT License. See ```LICENSE``` for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseungh06%2Fnode-sh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseungh06%2Fnode-sh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseungh06%2Fnode-sh/lists"}