{"id":18681304,"url":"https://github.com/psycofdj/xtdbash","last_synced_at":"2026-02-16T00:02:58.127Z","repository":{"id":51130301,"uuid":"109023151","full_name":"psycofdj/xtdbash","owner":"psycofdj","description":"Various helpers enhancing everyday life in bash shell","archived":false,"fork":false,"pushed_at":"2024-11-24T07:52:37.000Z","size":1032,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-24T08:27:40.581Z","etag":null,"topics":["bash","bash-history","bash-prompt","bosh","cloudfoundry","environment-variables","envloader","git","golang","gopath","json"],"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/psycofdj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-31T16:29:43.000Z","updated_at":"2024-11-24T07:52:41.000Z","dependencies_parsed_at":"2023-02-09T15:16:01.035Z","dependency_job_id":null,"html_url":"https://github.com/psycofdj/xtdbash","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psycofdj%2Fxtdbash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psycofdj%2Fxtdbash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psycofdj%2Fxtdbash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psycofdj%2Fxtdbash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/psycofdj","download_url":"https://codeload.github.com/psycofdj/xtdbash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231548341,"owners_count":18393558,"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","bash-history","bash-prompt","bosh","cloudfoundry","environment-variables","envloader","git","golang","gopath","json"],"created_at":"2024-11-07T10:06:50.011Z","updated_at":"2025-10-07T18:06:55.965Z","avatar_url":"https://github.com/psycofdj.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc --\u003e\n**Table of Contents**\n\n- [Modules](#modules)\n- [Quick start](#quick-start)\n- [API reference](#api-reference)\n    - [promptcmd](#promptcmd)\n    - [envloader](#envloader)\n    - [historysync](#historysync)\n    - [lastdir](#lastdir)\n    - [aliases](#aliases)\n    - [git](#git)\n    - [cf](#cf)\n    - [bosh](#bosh)\n    - [godev](#godev)\n    - [cdevent](#cdevent)\n    - [tools](#tools)\n\n\u003c!-- markdown-toc end --\u003e\n\n\n# Modules\n\n- [promptcmd](#promptcmd)     : screen-wide prompt line with configurable informations\n- [envloader](#envloader)     : load environment variables from json file found in directory tree\n- [historysync](#historysync) : synchronize command history across sessions\n- [lastdir](#lastdir)         : remember last directory and restore it on new session\n- [aliases](#aliases)         : define standard aliases\n- [git](#git)                 : display current git status in prompt line\n- [cf](#cf)                   : display current cloud foundry [target](https://github.com/guidowb/cf-targets-plugin) to prompt line (with completion)\n- [bosh](#bosh)               : display current [bosh](https://bosh.io/) target in prompt line and completion\n- [godev](#godev)             : navigate among *GO* projects available in current GOPATH (with completion)\n- [cdevent](#cdevent)         : manage commands to run when changing directory\n- [cdstack](#cdstack)         : stack directories visited in current bash (à la `pushd`/`popd`)\n- [tools](#tools)             : various helper functions\n\n# Quick start\n\n1. Clone XtdBash\n\n```bash\ncd \u003cinstall-directory-root\u003e\ngit clone https://github.com/psycofdj/xtdbash.git\n```\n\n2. Append the following to your bashrc:\n\n```bash\n. \u003cinstall-directory-root\u003e/xtdbash/xtdbash\n\n# initialize xtdbash with desired modules\nxtdbash_init \\\n  aliases \\\n  promptcmd \\\n  envloader \\\n  historysync \\\n  lastdir \\\n  git \\\n  cf \\\n  bosh \\\n  godev \\\n  cdstack\n\n# sources any file found in ~/.bashrc.*\nxtdbash_externals\n\n# (optional) display number of loaded files in prompt labels\nenvloader_enable_prompt\n\n# (optional) activates git branch in prompt line\ngit_enable_prompt\n\n# (optional) add cloud foundry target prompt label\ncf_enable_prompt\n\n# (optional) add bosh prompt labels (bosh V1 only)\nbosh_enable_prompt\n\n# activates screen-wide prompt line with side labels\npromptcmd_enable\n\n# register godev search paths\ngodev_add_namespace code.cloudfoundry.org 1\ngodev_add_namespace github.com 2\n\n# activates stacking of visited directories\ncdstack_enable\n```\n\n**Note**: Every module is optional but some require others.\n\n**Note MacOS**: In case of error like the following\n```\nreadlink: illegal option -- f\nusage: readlink [-n] [file ...]\nusage: dirname path\nxtdbash error: enable to find requested module aliases\n```\nyou can add `GNU coreutils` to your path to get appropriate `readlink`, `dirname`...\n```bash\nPATH=/usr/local/opt/coreutils/libexec/gnubin:${PATH}\n```\nI don't remember if this directory comes with `homebrew` or `port` installer.\n\n# API reference\n\nMain functions are loaded through ```xtdbash``` script.\n\n- ```xtdbash_init(name...)```: load modules given as arguments handling their dependencies\n- ```xtdbash_externals```: loads additional bash configuration files found in ```~/.bashrc.*```\n\n\nSee [quick start](#quick-start) section for an example.\n\n\n\n\n## promptcmd\n\n**requires**: [tools](#tools)\n\nThis module manages commands that must be run between each prompt display.\n\n\n- ```promptcmd_push(cmd)```: adds **cmd** to the list of commands to run on each prompt display\n\n- ```promptcmd_run```: run all registered prompt commands\n\n- ```promptcmd_enable```: register a command that replace default PS1 format\n  by colored full-line prompt. This prompt displays:\n  - type of environment (dev, rec or prod). This is deduced from hostname string.\n  - current login name\n  - current host name\n  - last command exit code (blinking red when non-zero)\n  - current time\n  - current directory\n  - additional labels given by ```PROMPTCMD_LABELS``` environment variable\n\n\n  ```PROMPTCMD_LABELS``` environment variable contains a semi-column delimited list of **items**,\n  where each items matches one of the following formats:\n  - ```text``` : display **text** as label with default color **lightmagenta**\n  - ```text|color``` : display **text** as label with given **color**\n\n    Valid color names are: *black*, *red*, *green*, *yellow*, *blue*, *magenta*, *cyan*, *white*,\n    *lightblack*, *lightred*, *lightgreen*, *lightyellow*, *lightblue*, *lightmagenta*, *lightcyan*,\n    *lightwhite*\n\n  **Note**: ```PROMPTCMD_LABELS``` is reset between each prompt. Variable should be set\n  in a function registered with ```promptcmd_push(cmd)```.\n\n- ```promptcmd_add_labels(item item...)```: add each arguments int ```PROMPTCMD_LABELS``` list\n\n- env variable `PROMTCMD_BLINK_OFF` controls blinking chars in prompt when previous\n  command returns non zero exit code. Setting `PROMTCMD_BLINK_OFF` to a non-empty value\n  suppresses blinking chars.\n\n## envloader\n\n**requires**: [cdevent](#cdevent) and [jq (external dep)](https://stedolan.github.io/jq/)\n\nThis module exports environment variables found in json files ```.env.json``` from\ncurrent directory to root filesystem.\n\nWhen a variable is set by multiple files, it gets its value from the closest ```.env.json```\n\nFor security reason, ```.env.json``` files **must** have **r--------** permissions. If not, file\nwill be ignored and a warning is emitted.\n\n- ```envloader_verbose_on()```:  enable verbose output for the module\n- ```envloader_verbose_off()```: disable verbose output for the module\n- ```envloader_edit([file])```: edit read-only env file. **files** default to ```./.env.json```\n- ```envloader_enable_prompt()```: display number of loaded variables in prompt labels\n- ```envloader_list()```: list all variables managed by envloader with their origin file\n- ```envloader_unload()```: unset all variables managed by envloader\n- ```envloader_run()```: search for ```.env.json``` files and set environment variables\n\n**Example**\n\n```bash\n# we declare variables for parent directory\necho '{ \"MYVAR1\" : \"1\", \"MYVAR2\" : \"2\" }' \u003e ../.env.json\nchmod 600 ../.env.json\n\n# we declare variables for current directory\necho '{ \"MYVAR3\" : \"2\", \"MYVAR1\" : \"overriden\" }' \u003e .env.json\nchmod 600 ./.env.json\n\n# we trigger envloader by 'changing' current directory\ncd .\n\n# display result\n# Note: MYVAR1 is multiply defined. Its gets its value from closest .env.json file\nenv | grep MYVAR | sort\nMYVAR1=overriden\nMYVAR2=2\nMYVAR3=3\n\n# same with envloader_list\nenvloader_list\n-\u003e MYVAR1 = overriden (\u003cdir\u003e/.env.json)\n-\u003e MYVAR2 = 2 (\u003cparent-dir\u003e/.env.json)\n-\u003e MYVAR3 = 3 (\u003cdir\u003e/.env.json)\n```\n\n**Live demo**\n\n![envloader](./docs/envloader.gif)\n\n**Pro tips** : working with dynamic PATH\n\nAt startup, envloader stores ```${PATH}``` in the variable ```${BASE_PATH}```. Because\njson content is bash-interpreted, you may declare the following ```.env.json``` file:\n```json\n{\n  \"GOPATH\": \"/home/user/dev/go\",\n  \"PATH\": \"${BASH_PATH}:${GOPATH}/bin\"\n}\n```\n\n**Pro tips** : using complex variable values\n\nThis module also works with objects and array values.\n```json\n{\n  \"GOPATH\"     : \"/home/user/go\",\n  \"DOCKER_ENV\" : {\n    \"name\"   : \"my-container\",\n    \"export\" : \"/mnt/data\",\n    \"ports\"  : [80, 443]\n  }\n}\n```\n\n```bash\nenvloader_list\n\n-\u003e     GOPATH = /home/user/go (\u003cpath\u003e/.env.json)\n-\u003e DOCKER_ENV = {\"name\":\"my-container\",\"export\":\"/mnt/data\",\"ports\":[80,443]} (\u003cpath\u003e/.env.json)\n```\n\n\n\n## historysync\n\n**requires**: [promptcmd](#promptcmd)\n\nSynchronize command history between bash instances.\n\n\n- ```historysync_off```: Disable history synchronization for this instance\n\n- ```historysync_on```: Enable history synchronization for this instance. Synchronization is **on**\n  by default.\n\n- ```historysync_run```: run history synchronization for current bash instance. This function is\n  automatically added to [promptcmd](#promptcmd).\n\n\n## lastdir\n\n**requires**: [cdevent](#cdevent)\n\nRemember last working directory and use it for future new bash sessions.\nThere is no api for this module, everything work by pushing special commands to\n[cdevent](#cdevent) module.\n\n\n## aliases\n\n**requires**: none\n\nBunch of pre-defined bash aliases and functions\n\n### Bash aliases functions\n\n| Alias | Command                                            | Description                                                 |\n|-------|----------------------------------------------------|-------------------------------------------------------------|\n| rm    | ```rm -i```                                        | enable confirmation prompt by default                       |\n| l     | ```ls -c -h -l --color=auto```                     | sort by name, human readbale sizes, list display and colors |\n| ll    | ```l -a```                                         | like `l` with hidden files                                  |\n| p     | ```pwd```                                          | display current working directory                           |\n| h     | ```cf ~```                                         | change to home directory                                    |\n| k     | ```cd ..```                                        | back to parent directory                                    |\n| e     | ```TERM=xterm-256color emacs -nw --no-site-file``` | run emacs with color compatibility                          |\n| c     | ```clear```                                        | clear screen                                                |\n| ps    | ```ps auxw --sort=uid,pid,cmd```                   | list all processes with sort options                        |\n| sudo  | ```sudo ```                                        | wraps `sudo` in alias, allowing to run aliases with sudo    |\n| tf    | ```terraform```                                    | runs terraform (Hashicorp product)                          |\n\n\n### Helper functions\n\n\n| Function                     | Description                                                                                   |\n|------------------------------|-----------------------------------------------------------------------------------------------|\n| ```grip-start```             | runs [grip](https://github.com/joeyespo/grip) docker image for current directory              |\n| ```grip-stop```              | stops [grip](https://github.com/joeyespo/grip) docker container running for current directory |\n| ```grip-show```              | opens running grip url in web browser using `sensible-browser`                                |\n| ```docker-ip \u003cname-or-id\u003e``` | display docker internal IP for container `name-or-id` with completion                         |\n| ```gogdb \u003cbin\u003e```            | run `\u003cbin\u003e` wrapped in `gdb` with Golang bindings                                             |\n\n\n## git\n\n**requires**: [promptcmd](#promptcmd)\n\n- ```git_enable_prompt```: populates ```PROMPTCMD_LABELS``` with current git branch name.\n    Selected color depends on current working tree status :\n  - **green**  : all modifications are committed, no untracked files\n  - **yellow** : all modifications are committed, some untracked files\n  - **red** : some uncommitted changes\n\n**Live demo**\n\n![git](./docs/git.gif)\n\n## cf\n\n**requires**: [promptcmd](#promptcmd) and [targets (external dep)](https://github.com/guidowb/cf-targets-plugin)\n\nThis module shows current cloud foundry target in promptcmd labels. It relies\non [targets](https://github.com/guidowb/cf-targets-plugin) plugin that maintains\nmultiple targets on top of *cf* cli.\n\nIt also provides a completion for ```cf``` command that handles *targets* plugin.\n(See [issue #1116](https://github.com/cloudfoundry/cli/issues/1116) that explains\nwhy cloud foundry plugins don't have builtin bash completion)\n\n- ```cf_enable_prompt()``` : detects current cf target name and push it as label\n  in promptcmd.\n\n**Live demo**\n\n![cf example](./docs/cf.gif)\n\n## bosh\n\n**requires**: [promptcmd](#promptcmd)\n\nThis module shows current bosh-V1 target in promptcmd labels. It also provides\ncompletion for bosh-V2\n\n- ```bosh_enable_prompt()``` : detects current bosh-V1 target name and push it as label\n  in promptcmd.\n\n**Live demo**\n\n![bosh example](./docs/bosh.gif)\n\nFor bosh-V2, module provides standard cli completion and addition alias search for\n```-e|--environment``` flags. Completions are automatically started at module load.\n\n\n## godev\n\n**requires**: [tools](#tools)\n\nThis module provides a function that searches projects in *GOPATH* for\ngiven name and change directory into it.\n\nWhen multiple items matches given name, the function emits a warning\nand shows all found directories.\n\nIn addition, the module comes with a bash-completion script that completes\nuser input according to matching folder of *GOPATH*. Matches include repository\nnames (eg. github.com), repository namespaces and project names.\n\n- ```godev name```: searches for given name in current *GOPATH* and ```cd``` into\n  directory if a single item is found.\n\n- ```godev_add_namespace host deth```: add given repository host in search paths.\n  second arguments tells how deep godev and its completion should search. Typically\n  in *github.com's* hierarchy, we want to search in two levels : **(namespace)/(project)**.\n  In other repositories such as *code.cloudfoundry.com*, we only need 1 layer.\n\n**Live demo**\n\n![cf example](./docs/godev.gif)\n\n## cdevent\n\n**requires**: [tools](#tools)\n\nManage a list of commands to run when changing directory. This works by decorating\nthe builtin command ```cd``` by an internal function.\n\n- ```cdevent_push cmd```: adds **cmd** to the command list to run when changing directory.\n\n## cdstack\n\n**requires**: [cdevent](#cdevent)\n\nDecorate `cd` builtin to stack visited directories. This stack is handled with specific\noptions to `cd` command:\n\n- `-s`: list all directories in the stack, most recently visited first. Directories are\nnumbered starting from 0.\n- `-\u003cn\u003e`: cd to \u003cn\u003eth directory in the stack. Usefull right after `cd -s`.\n- `-`: cd to previous directory in stack, use `cd -s` to view the stack.\n- `+`: cd to last directory in stack, use `cd -s` to view the stack.\n- `-c`: clear the stack. It is then initialized with the current directory.\n- `-c \u003cn\u003e`: remove the nth directory from stack. `cd -c 0` will remove the first and go to\nthe previous directory.\n- `-c \u003ck\u003e..\u003cn\u003e`: remove directories starting  from kth to nth, then go to first directory\nin the modified stack. If `k` is omitted, it's replaced by 0, if `n` is omitted, it's\nreplaced by the last index.\n\n## tools\n\nProvides a list of helper functions.\n\n- ```decorate_builtin builtin pre post```: decorates the builtin function **builtin** with\n  **pre** that runs before the builtin and **post** that runs after the builtin\n\n\n\u003c!-- - ```decorate_function fn pre post```: decorates the function **fn** with --\u003e\n\u003c!--   **pre** that runs before the function and **post** that runs after the function --\u003e\n\n- ```strlist_add name value```: appends **value** to semi-column separated string list\n  hold by variable **name**\n\n\u003c!-- Local Variables: --\u003e\n\u003c!-- ispell-local-dictionary: \"american\" --\u003e\n\u003c!-- End: --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsycofdj%2Fxtdbash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpsycofdj%2Fxtdbash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsycofdj%2Fxtdbash/lists"}