/xtdbash

Various helpers enhancing everyday life in bash shell

Primary LanguageShell

Table of Contents

Modules

  • promptcmd : screen-wide prompt line with configurable informations
  • envloader : load environment variables from json file found in directory tree
  • historysync : synchronize command history across sessions
  • lastdir : remember last directory and restore it on new session
  • aliases : define standard aliases
  • git : display current git status in prompt line
  • cf : display current cloud foundry target to prompt line (with completion)
  • bosh : display current bosh target in prompt line and completion
  • godev : navigate among GO projects available in current GOPATH (with completion)
  • cdevent : manage commands to run when changing directory
  • cdstack : stack directories visited in current bash (à la pushd/popd)
  • tools : various helper functions

Quick start

  1. Clone XtdBash
cd <install-directory-root>
git clone https://github.com/psycofdj/xtdbash.git
  1. Append the following to your bashrc:
. <install-directory-root>/xtdbash/xtdbash

# initialize xtdbash with desired modules
xtdbash_init \
  aliases \
  promptcmd \
  envloader \
  historysync \
  lastdir \
  git \
  cf \
  bosh \
  godev \
  cdstack

# sources any file found in ~/.bashrc.*
xtdbash_externals

# (optional) display number of loaded files in prompt labels
envloader_enable_prompt

# (optional) activates git branch in prompt line
git_enable_prompt

# (optional) add cloud foundry target prompt label
cf_enable_prompt

# (optional) add bosh prompt labels (bosh V1 only)
bosh_enable_prompt

# activates screen-wide prompt line with side labels
promptcmd_enable

# register godev search paths
godev_add_namespace code.cloudfoundry.org 1
godev_add_namespace github.com 2

# activates stacking of visited directories
cdstack_enable

Note: Every module is optional but some require others.

Note MacOS: In case of error like the following

readlink: illegal option -- f
usage: readlink [-n] [file ...]
usage: dirname path
xtdbash error: enable to find requested module aliases

you can add GNU coreutils to your path to get appropriate readlink, dirname...

PATH=/usr/local/opt/coreutils/libexec/gnubin:${PATH}

I don't remember if this directory comes with homebrew or port installer.

API reference

Main functions are loaded through xtdbash script.

  • xtdbash_init(name...): load modules given as arguments handling their dependencies
  • xtdbash_externals: loads additional bash configuration files found in ~/.bashrc.*

See quick start section for an example.

promptcmd

requires: tools

This module manages commands that must be run between each prompt display.

  • promptcmd_push(cmd): adds cmd to the list of commands to run on each prompt display

  • promptcmd_run: run all registered prompt commands

  • promptcmd_enable: register a command that replace default PS1 format by colored full-line prompt. This prompt displays:

    • type of environment (dev, rec or prod). This is deduced from hostname string.
    • current login name
    • current host name
    • last command exit code (blinking red when non-zero)
    • current time
    • current directory
    • additional labels given by PROMPTCMD_LABELS environment variable

    PROMPTCMD_LABELS environment variable contains a semi-column delimited list of items, where each items matches one of the following formats:

    • text : display text as label with default color lightmagenta

    • text|color : display text as label with given color

      Valid color names are: black, red, green, yellow, blue, magenta, cyan, white, lightblack, lightred, lightgreen, lightyellow, lightblue, lightmagenta, lightcyan, lightwhite

    Note: PROMPTCMD_LABELS is reset between each prompt. Variable should be set in a function registered with promptcmd_push(cmd).

  • promptcmd_add_labels(item item...): add each arguments int PROMPTCMD_LABELS list

  • env variable PROMTCMD_BLINK_OFF controls blinking chars in prompt when previous command returns non zero exit code. Setting PROMTCMD_BLINK_OFF to a non-empty value suppresses blinking chars.

envloader

requires: cdevent and jq (external dep)

This module exports environment variables found in json files .env.json from current directory to root filesystem.

When a variable is set by multiple files, it gets its value from the closest .env.json

For security reason, .env.json files must have r-------- permissions. If not, file will be ignored and a warning is emitted.

  • envloader_verbose_on(): enable verbose output for the module
  • envloader_verbose_off(): disable verbose output for the module
  • envloader_edit([file]): edit read-only env file. files default to ./.env.json
  • envloader_enable_prompt(): display number of loaded variables in prompt labels
  • envloader_list(): list all variables managed by envloader with their origin file
  • envloader_unload(): unset all variables managed by envloader
  • envloader_run(): search for .env.json files and set environment variables

Example

# we declare variables for parent directory
echo '{ "MYVAR1" : "1", "MYVAR2" : "2" }' > ../.env.json
chmod 600 ../.env.json

# we declare variables for current directory
echo '{ "MYVAR3" : "2", "MYVAR1" : "overriden" }' > .env.json
chmod 600 ./.env.json

# we trigger envloader by 'changing' current directory
cd .

# display result
# Note: MYVAR1 is multiply defined. Its gets its value from closest .env.json file
env | grep MYVAR | sort
MYVAR1=overriden
MYVAR2=2
MYVAR3=3

# same with envloader_list
envloader_list
-> MYVAR1 = overriden (<dir>/.env.json)
-> MYVAR2 = 2 (<parent-dir>/.env.json)
-> MYVAR3 = 3 (<dir>/.env.json)

Live demo

envloader

Pro tips : working with dynamic PATH

At startup, envloader stores ${PATH} in the variable ${BASE_PATH}. Because json content is bash-interpreted, you may declare the following .env.json file:

{
  "GOPATH": "/home/user/dev/go",
  "PATH": "${BASH_PATH}:${GOPATH}/bin"
}

Pro tips : using complex variable values

This module also works with objects and array values.

{
  "GOPATH"     : "/home/user/go",
  "DOCKER_ENV" : {
    "name"   : "my-container",
    "export" : "/mnt/data",
    "ports"  : [80, 443]
  }
}
envloader_list

->     GOPATH = /home/user/go (<path>/.env.json)
-> DOCKER_ENV = {"name":"my-container","export":"/mnt/data","ports":[80,443]} (<path>/.env.json)

historysync

requires: promptcmd

Synchronize command history between bash instances.

  • historysync_off: Disable history synchronization for this instance

  • historysync_on: Enable history synchronization for this instance. Synchronization is on by default.

  • historysync_run: run history synchronization for current bash instance. This function is automatically added to promptcmd.

lastdir

requires: cdevent

Remember last working directory and use it for future new bash sessions. There is no api for this module, everything work by pushing special commands to cdevent module.

aliases

requires: none

Bunch of pre-defined bash aliases and functions

Bash aliases functions

Alias Command Description
rm rm -i enable confirmation prompt by default
l ls -c -h -l --color=auto sort by name, human readbale sizes, list display and colors
ll l -a like l with hidden files
p pwd display current working directory
h cf ~ change to home directory
k cd .. back to parent directory
e TERM=xterm-256color emacs -nw --no-site-file run emacs with color compatibility
c clear clear screen
ps ps auxw --sort=uid,pid,cmd list all processes with sort options
sudo sudo wraps sudo in alias, allowing to run aliases with sudo
tf terraform runs terraform (Hashicorp product)

Helper functions

Function Description
grip-start runs grip docker image for current directory
grip-stop stops grip docker container running for current directory
grip-show opens running grip url in web browser using sensible-browser
docker-ip <name-or-id> display docker internal IP for container name-or-id with completion
gogdb <bin> run <bin> wrapped in gdb with Golang bindings

git

requires: promptcmd

  • git_enable_prompt: populates PROMPTCMD_LABELS with current git branch name. Selected color depends on current working tree status :
    • green : all modifications are committed, no untracked files
    • yellow : all modifications are committed, some untracked files
    • red : some uncommitted changes

Live demo

git

cf

requires: promptcmd and targets (external dep)

This module shows current cloud foundry target in promptcmd labels. It relies on targets plugin that maintains multiple targets on top of cf cli.

It also provides a completion for cf command that handles targets plugin. (See issue #1116 that explains why cloud foundry plugins don't have builtin bash completion)

  • cf_enable_prompt() : detects current cf target name and push it as label in promptcmd.

Live demo

cf example

bosh

requires: promptcmd

This module shows current bosh-V1 target in promptcmd labels. It also provides completion for bosh-V2

  • bosh_enable_prompt() : detects current bosh-V1 target name and push it as label in promptcmd.

Live demo

bosh example

For bosh-V2, module provides standard cli completion and addition alias search for -e|--environment flags. Completions are automatically started at module load.

godev

requires: tools

This module provides a function that searches projects in GOPATH for given name and change directory into it.

When multiple items matches given name, the function emits a warning and shows all found directories.

In addition, the module comes with a bash-completion script that completes user input according to matching folder of GOPATH. Matches include repository names (eg. github.com), repository namespaces and project names.

  • godev name: searches for given name in current GOPATH and cd into directory if a single item is found.

  • godev_add_namespace host deth: add given repository host in search paths. second arguments tells how deep godev and its completion should search. Typically in github.com's hierarchy, we want to search in two levels : (namespace)/(project). In other repositories such as code.cloudfoundry.com, we only need 1 layer.

Live demo

cf example

cdevent

requires: tools

Manage a list of commands to run when changing directory. This works by decorating the builtin command cd by an internal function.

  • cdevent_push cmd: adds cmd to the command list to run when changing directory.

cdstack

requires: cdevent

Decorate cd builtin to stack visited directories. This stack is handled with specific options to cd command:

  • -s: list all directories in the stack, most recently visited first. Directories are numbered starting from 0.
  • -<n>: cd to th directory in the stack. Usefull right after cd -s.
  • -: cd to previous directory in stack, use cd -s to view the stack.
  • +: cd to last directory in stack, use cd -s to view the stack.
  • -c: clear the stack. It is then initialized with the current directory.
  • -c <n>: remove the nth directory from stack. cd -c 0 will remove the first and go to the previous directory.
  • -c <k>..<n>: remove directories starting from kth to nth, then go to first directory in the modified stack. If k is omitted, it's replaced by 0, if n is omitted, it's replaced by the last index.

tools

Provides a list of helper functions.

  • decorate_builtin builtin pre post: decorates the builtin function builtin with pre that runs before the builtin and post that runs after the builtin
  • strlist_add name value: appends value to semi-column separated string list hold by variable name