shell

How to navigate/browse shell history in Linux (using hstr/hh)

hstr@github is a ncurses used to view, navigate, select and search command history from bash and zsh. Its an improved history|grep or ctrl-r.

$ wget https://github.com/dvorka/hstr/releases/download/1.16/hh-1.16-bin-64b.tgz -O - | tar -xz

# ncurses list of history filtered by PATTERN
$ hh PATTERN
# use options
$ HH_CONFIG=hicolor,regexp hh

from hstr: history the easy way

How to change bash prompt (using PS1, git-prompt.sh, liquid-prompt, bash-it and powerline)

PS: prompt statement: PS1 default, PS2 continuation, PS3 select shell scripts, PS4 "set-x" prefix
PROMPT_COMMAND: executes the content of the PROMPT_COMMAND just before displaying the PS1 variable
see http://www.thegeekstuff.com/2008/09/bash-shell-take-control-of-ps1-ps2-ps3-ps4-and-prompt_command/
PS1 shoud be set in {~/.basrc,/etc/bashrc} because non-interactive bashes go out of their way to unset PS1

# display username \u, hostname \h, FQDN \H, current working directory \w and basename of cwd \W
PS1="\u@\h \w\$"

# display time in 24h format \t, in 12h format \T in am/pm format \@ and date \D{format} in strftime(3)
PS1="\u@\h [\t]$" 

# display command output \$(cmd) or `cmd`, history number \!, last command status \$?, env variable $var
PS1="\! \h \$(uname -r) \$?$" 

# change foreground color \e[x;ym $PS1 \e[m where \e[ is start color scheme, x;y is color pair and \e[m is stop color scheme
PS1="\e[0;31m[\u@\h \W]\$ \e[m $"
txtblk='\e[0;30m' # Black - Regular
txtred='\e[0;31m' # Red
txtgrn='\e[0;32m' # Green
txtylw='\e[0;33m' # Yellow
txtblu='\e[0;34m' # Blue
txtpur='\e[0;35m' # Purple
txtcyn='\e[0;36m' # Cyan
txtwht='\e[0;37m' # White
# change to 1 for bold and 4 for underline

# change background color \e[{code}m
PS1="\e[47m\u@\h \w> \e[m"
bakblk='\e[40m'   # Black - Background
bakred='\e[41m'   # Red
bakgrn='\e[42m'   # Green
bakylw='\e[43m'   # Yellow
bakblu='\e[44m'   # Blue
bakpur='\e[45m'   # Purple
bakcyn='\e[46m'   # Cyan
bakwht='\e[47m'   # White
txtrst='\e[0m'    # Text Reset

# change the prompt color using 'tput setab|setb|setaf|setf' background|foreground and 'tput bold|dim|smul|rmul|rev' bold|dim|underline|reverse
PS1="\[$(tput bold)$(tput setb 4)$(tput setaf 7)\]\u@\h:\w $ \[$(tput sgr0)\]"

# positioning the cursor \[33[;f\], save cursor position \[33[s\], restore \[33[u\]
PS1=">\[33[s\]\[33[1;\$((COLUMNS-4))f\]\$(date +%H:%M)\[33[u\]"

# rhel default
PS1="[\u@\h \W]\\$ "
# ubuntu default
PS1="\u@\h:\W\\$ "
# see https://www.kirsle.net/wizards/ps1.html

from ColorBashPrompt@arch, examples@thegeekstuff and ColorBashPrompt@cyberciti

# add git prompt
$ cat ~/.bashrc
. /usr/lib/git-core/git-sh-prompt
export PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '

# by defaults only shows current branch name
GIT_PS1_SHOWDIRTYSTATE show unstaged '*' and staged '+' changes 
GIT_PS1_SHOWSTASHSTATE show '$' if something is stashed
GIT_PS1_SHOWUNTRACKEDFILES shows '%' if untracked files
GIT_PS1_SHOWUPSTREAM="auto" shows '','','=' if behind/ahead/diverged/nodiff
GIT_PS1_SHOWUPSTREAM="verbose name" show number of commits ahead/behind (+/-) upstream, and upstream name

from git-prompt.sh

  • liquidprompt@github is an adaptive, smart prompt for Bash and Zsh. It can display various useful information on the shell prompt, only when it's needed.
## install
$ git clone https://github.com/nojhan/liquidprompt.git ~/.liquidprompt
$ cp ~/.liquidprompt/liquidpromptrc-dist ~/.config/liquidpromptrc
$ cat ~/.bashrc
. ~/.liquidprompt/liquidprompt

## usage ~/.config/liquidpromptrc
LP_PS1_PREFIX/LP_PS1_POSTFIX adds prefix/suffix, 'prompt_tag MYTAG' is same as 'LP_PS1_PREFIX'
LP_PS1/LP_PS1_FILE rearranging the prompt, see ~/.liquidprompt/liquid.ps1
LP_ENABLE_XXX enable a feature, e.g.: LP_ENABLE_TIME, LP_ENABLE_RUNTIME 
LP_HOSTNAME_ALWAYS/LP_USER_ALWAYS display if differs from current
'prompt_off/prompt_on' temporally disable/enable

# branch_name(+lines_added/-lines_removed,pending_commits)
# branch_name in green if up-to-date, red if changes, yellow if pending commits to push
# yellow '+' if shashed modification, red '*' if untracked files
[me:~/gitrepo] master(+1/-2)*

## uninstall
# remove '. ~/.liquidprompt/liquidprompt' from '~/.bashrc'
$ rm -rf ~/.config/liquidpromptrc ~/.liquidprompt

from liquid-prompt@ubuntu

  • bash-it@github is a mash up of my own bash commands and scripts, other bash stuff I have found. A shameless ripoff of oh-my-zsh.
## install
$ sudo pip install argcomplete
$ git clone https://github.com/revans/bash-it.git ~/.bash_it
$ cp ~/.bash_profile{,.bak}
$ ~/.bash_it/install.sh
$ for pg in chruby chruby-auto postgres z; do bash-it disable plugin $pg; done
$ . ~/.bash_profile

## enable theme, see https://github.com/revans/bash-it/wiki/Themes
$ cat ~/.bash_profile
# location ~/.bash_it/themes/
export BASH_IT_THEME='bobby'
$ reload

## uninstall
$ cp ~/.bash_profile{.bak,}
$ rm -rf ~/.bash_it ~/.bash_profile.bak
  • powerline@github is a statusline plugin for vim, and provides statuslines and prompts for several other applications, including zsh, bash, tmux, vim …
## install
$ sudo apt-get install powerline (14.10 very old)
or
$ sudo apt-get install python-pip git
$ sudo pip install git+git://github.com/Lokaltog/powerline

# install fonts
$ sudo wget -q https://github.com/Lokaltog/powerline/raw/develop/font/PowerlineSymbols.otf -O /usr/share/fonts/PowerlineSymbols.otf
$ sudo fc-cache -vf
$ sudo wget -q https://github.com/Lokaltog/powerline/raw/develop/font/10-powerline-symbols.conf -O /etc/fonts/conf.d/10-powerline-symbols.conf
# restart all terms

# if you get "coercing to Unicode" then see https://github.com/powerline/powerline/issues/835 and
$ cd /usr/lib/python2.7/dist-packages/
$ sudo wget -q https://github.com/powerline/powerline/commit/ecf26dfbc65e0c39001e8283e776c50899f90e1b.patch
$ sudo patch -p1 < *.patch

## usage
# ~/.{bash,zsh}rc or /etc/{bash.bashrc,zsh/zshrc}
export POWERLINE=/usr/local/lib/python2.7/dist-packages/powerline
if [ -f $POWERLINE/bindings/{bash,zsh}/powerline.sh ]; then
    source $POWERLINE/bindings/{bash,zsh}/powerline.sh
fi
# ~/.tmux.conf
export POWERLINE=/usr/lib/python2.7/dist-packages/powerline
source $POWERLINE/bindings/tmux/powerline.conf
set-option -g default-terminal "screen-256color"
# ~/.vimrc or /etc/vim/vimrc
set rtp+=/usr/local/lib/python2.7/dist-packages/powerline/bindings/vim/
" Always show statusline
set laststatus=2
" Use 256 colours (Use this setting only if your terminal supports 256 colours)
set t_Co=256

## configuration
mkdir ~/.config/powerline
cp -R $POWERLINE/config_files/* ~/.config/powerline
# bash doesnt support right segments, so edit ~/.config/powerline/config.json
    "theme": "default_leftonly"
# add hostname to prompt, edit ~/.config/powerline/themes/shell/{default,_leftonly}.json
    "only_if_ssh": false

## uninstall
$ sudo pip uninstall powerline
or
$ sudo rm -rf /usr/local/bin/powerline* /usr/local/lib/python2.7/dist-packages/powerline ~/.config/powerline

from docs and powerline@ubuntu

How to control media player from CLI using D-Bus/MPRIS

  • MPRIS is a standard dbus interface for programmatic control media players any media player
## install
$ sudo apt-get install qtchooser

## using (clementine)
$ show information about the currently playing song
$ qdbus org.mpris.clementine /Player org.freedesktop.MediaPlayer.GetMetadata
# same but v2
$ qdbus org.mpris.MediaPlayer2.clementine /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get org.mpris.MediaPlayer2.Player Metadata
# show all mpris players running
$ qdbus org.mpris.MediaPlayer2.*

# control player
$ qdbus org.mpris.clementine /Player org.freedesktop.MediaPlayer.Pause
$ qdbus org.mpris.clementine /Player org.freedesktop.MediaPlayer.VolumeSet 50

from MPRIS@clementine

## install
$ sudo apt-get install mpris-remote

## using
# uses that first media player or MPRIS_REMOTE_PLAYER env
$ mpris-remote identity
# shows current player status, song playing
$ mpris-remote
# shows current track info tags
$ mpris-remote trackinfo
# shows corrent player status
$ mpris-remote playstatus

# control player and volume
$ mpris-remote prev|next|play|stop|pause
$ mpris-remote volume 

# populates current playlist
$ mpris-remote clear
$ find ~/music -name '*.mp3' | mpris-remote addtrack -

# eg: bash prompt with media info
function mpris { echo `{ mpris-remote trackinfo && mpris-remote playstatus; } | sed -n -r 's,'$1': (.*),\1,p'`; }
export PS1_old="$PS1"
export PS1="\$(mpris playing) \$(mpris title)\n$PS1_old"

How to create a self-extracting archive in Linux (using makeself)

makeself is a small shell script that generates a self-extractable tar.gz archive from a directory and adds a small shell script stub at the beginning of the archive to initiate self-extraction, and guide installation of extracted files.

# install from srpm, for el/centos
$ rpmbuild --rebuild http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/source/SRPMS/m/makeself-2.2.0-3.fc21.src.rpm
$ rpm -Uv makeself-*.rpm

# install for debian/ubuntu
$ sudo apt-get install makeself

# create a self-extractng archive
$ makeself.sh --notemp ./backup ./backup.run "SFX archive for backup" echo "Extraction done"

# extract
$ ./backup.run

# create a self-extracting installer
$ touch /program/installer.sh ; chmod 755 ./program/install.sh
$ makeself.sh ./program ./program.run "SFX installer for program" ./install.sh

from How to create a self-extracting archive or installer in Linux

How to detach a Linux process from shell (using bg/disown/nohup)

Linux will automatically a child process by sending SIGINT when parent (a shell exit) ends. To avoid this you must detach the child from the parent.

  • disown: Prevents a closing shell from sending SIGUP signals.
$ cmd & 
# or hit CTRL-Z to interrupt and bg
$ gb
[1] cmd &

# disown is supported in bash and zsh, but shells like csh, tcsh, dash do not support it
$ disown %1

see fg@cyberciti and disown@cyberciti

$ nohup cmd &

# nohupping backgrounded jobs is typically used to avoid terminating them when logging off from a remote SSH session
$ cmd </dev/null &>/dev/null &
or
$ nohup cmd > foo.out 2> foo.err < /dev/null &

see nohup@cyberciti

  • tmux@wiki/gnu screen@wiki: can also detach a process from the current shell. It allows one to reattach to the process later on.
# run cmd detached from SIGHUP and in the background
$ screen -A -m -d -S somename cmd &

from How to detach a Linux process from shell