Skip to content

Instantly share code, notes, and snippets.

@mtesseracted
Created October 22, 2019 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtesseracted/d60a4bfd7f2ae007e9f1c7065e57b68c to your computer and use it in GitHub Desktop.
Save mtesseracted/d60a4bfd7f2ae007e9f1c7065e57b68c to your computer and use it in GitHub Desktop.
# ~/.bashrc: executed by bash(1) for non-login shells.
# ______________________________________________________________________
# / \
# ( Ubuntu defaults )
# \______________________________________________________________________/
#
# If not running interactively, don't do anything
case $- in *i*);; *) return;; esac
# Shell options
HISTCONTROL=ignoreboth # ignore duplicates, man bash for more
HISTSIZE=1000
HISTFILESIZE=80000
shopt -s histappend # append history, not overwrite
shopt -s checkwinsize # check win size after each command
shopt -s globstar # ** globs recursively
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
# ______________________________________________________________________
# / \
# ( Environment vars )
# \______________________________________________________________________/
#
GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;'
export GCC_COLORS="${GCC_COLORS}32:locus=01:quote=01" # color GCC output
export OMP_NUM_THREADS=2
#export I_MPI_SHM_LMT=shm # alternative mpihack
[ -z "$HOME" ] && HOME="$PWD"
# intel vars sourced in /etc/bash.bashrc from /opt/intel/parallel.../psxevars.sh
# ______________________________________________________________________
# / \
# ( Misc. Aliases )
# \______________________________________________________________________/
#
alias ll='ls -Al'
alias p3="python3"
alias xo="xdg-open"
alias bcl="bc -l"
alias les="less -iSR"
alias gstat="git status -b -unormal --porcelain"
# grep color: ignore binaries, use regex, ignore vim shadows and doxygen dirs
alias grepc="grep --color=always -IE --exclude=*~ --exclude-dir={html,latex}"
alias mpihack="echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope"
if [ -x /usr/bin/dircolors ]; then # color support/aliases
test -r ~/.dircolors &&\
eval "$(dircolors -b ~/.dircolors)" ||\
eval "$(dircolors -b)"
alias ls='ls --color=auto --hide=*~'
alias grep='grep --color=auto'
fi
# ______________________________________________________________________
# / \
# ( Custom commands )
# \______________________________________________________________________/
#
# future ideas:
# a grep that returns the function/subr a matched string resides in
# use grep -n to return line nums first, which also gives filename, so
# can sort based on extension (fortran, c, py, sh, ...)
# Note: search should be case-insensitive
# c/c++ extensions: c cc cpp c++ h hpp
# fortran extensions: f f77 f90 f95 f03 f08
# vim view clearer (vvclear): arg1 is how many of the newest entries to clear,
# so it will go into $HOME/.vim/view/ and delete the last n entries
if $(notify-send --version &>/dev/null); then
alert() {
# alert for long running commands. Usage:> sleep 1; alert
[ $? = 0 ] && local icon='terminal' || local icon='error'
local prevcmd="$(history |tail -1 |\
sed -e 's/^\s*[0-9]\+\s*//;s/\;\s*alert$//')"
notify-send --urgency=low -i $icon $prevcmd
}
fi
screenrec(){
# record the screen to a video file
# args: [h|help|-h|--help] help message
# [] record the whole desktop
# [0] use the calling window's dimensions
# [1] select the window to record
#if [[ "$1" == +(h|help|-h|--help) ]]; then
if [[ "$1" != +(''|0|1) ]]; then
echo "Usage:> screenrec [|0|1] (blank: whole desktop,"
echo " 0: calling window's dimensions,"
echo " 1: select window to capture)"
return 1
fi
local srec scinf="$(xwininfo -id $WINDOWID)" # size to record, xwininfo
local wd ht x0=0 y0=0 # width, height, x/y offset
local odir="$HOME/Videos/screenrec" # output directory
mkdir -p $odir
if [[ "$1" == 1 ]]; then
echo 'Select window to caputre now...'
scinf="$(xwininfo)"
fi
if [[ "$1" == +(0|1) ]]; then
x0=$(echo -e "$scinf" |grep 'Absolute upper-left X' |awk '{print $4}')
y0=$(echo -e "$scinf" |grep 'Absolute upper-left Y' |awk '{print $4}')
wd=$(echo -e "$scinf" |grep 'Width:' |awk '{print $2}')
ht=$(echo -e "$scinf" |grep 'Height:' |awk '{print $2}')
srec="${wd}x${ht}"
else
srec=$(xdpyinfo |grep dimensions |awk '{print $2}')
fi
ffmpeg -y -f x11grab -framerate 40 -s ${srec} \
-i ${DISPLAY}.0+${x0},${y0} -vcodec libx264rgb \
$odir/recording-$(date +%Y%m'('%R:%S')').mp4
}
findsub(){
# find as a substring, case insensitive, errors supressed
# could switch to a subshell.. echo -e "$(find ..
find $PWD -iname "*${1}*" -follow 2>/dev/null
}
findsub2(){
# more comprehensive test version with tmp var for errors
# to try to handle permission denied separately
# NB: find option -nowarn doesn't affect permision denied stuff
fout=$(find $PWD -name "*${1}*" -follow 2>&1)
local fexit=$?
local IFS=$'\n'
for f in ${fout}; do #This assumes IFS=$'\n'
! $(echo -n "$f" |grep -qe 'find: .*: Permission denied') &&\
echo -e "$f" || \
FIND3ERRS="$FIND3ERRS$f\n"
done
return $fexit
}
which2(){
# print the type of arg1, e.g. function, builtin, alias, executable
# if exectuable, give `ls` info about the arg [& symlink location]
if [ "$#" -ne 1 ]; then
echo 'Usage:> which2 <cmd_name>'
return 1
fi
local var1 # alias
local var2=false # executable/exists
local var3=$(type -t "$1" 2>/dev/null) # bash func
# check for function/builtin
if [ "$var3" = 'function' ] || [ "$var3" = 'builtin' ]; then
printf "$1 is a bash $var3\n" # print type info
var2=true # it's at LEAST a funciton/builtin
fi
var3="$1" # now set as arg1
# check for alias
var1=$(alias "$1" 2>/dev/null) # alias
if [ "$?" -eq 0 ]; then
printf "$var1\n" # print the alias
var2=true # it's at LEAST an alias
var3="${var1#*=}" # get alias'd command
var3="${var3:1:-1}" # remove quotes
var3="${var3%%' '*}" # remove any args
fi
# Check for executable
var1=$(which "$var3" 2>/dev/null) # checking arg1 or alias cmd
if [ -n "$var1" ]; then
var3=$(readlink -f "$var1") # check for symlinks
if [ "$var3" = "$var1" ]; then
ls --color=always -lh "$var1" |cut -f 4- -d ' '
else
var1="$(ls --color=always -lh $var1 $var3 |cut -f 4- -d' ')"
printf "LINK: ${var1/$'\n'/$'\nSRC : '}\n"
fi
elif ! $var2; then
return 1 # no command found
fi
}
grep2(){
# find all files that contain all arg strings supplied
# in the current directory (recursively, case insensitive)
[ "$#" -lt 2 ] &&\
echo "Usage:> grep2 <str1> <str2> [str3] ..." && return 1
local errfil="$HOME/alm_grep2tmp.err"
local ms=$(grep -ril "$1" 2>$errfil) #matches
local es=$? # exit status
#echo "String $1 file count: $(echo -e "$ms" |wc -l), ?: $es"
if [ -n "$ms" ]; then #exit at a not found
shift; local ms2=""
for s in "${@}"; do # need xargs to not exceed grep input limit
ms2=$(echo -e "$ms" |xargs grep -il "$s" 2>$errfil)
es=$?
if [ -z "$ms2" ]; then
cat $errfil 2>/dev/null; rm -f $errfil
# map xargs not found to grep not found exit status
[ $es -eq 123 ] && return 1
return $es
fi
ms="$ms2"; ms2='' #update to smaller file list
done
cat $errfil 2>/dev/null; rm -f $errfil
echo -e "$ms"
else
cat $errfil 2>/dev/null; rm -f $errfil
return $es
fi
}
lstr(){
# wrapper for $> ls -lhtr |tail -5
# @TODO: get to work with wildcards $> lstr l*.out
# prob not possible since bash expands before passing args.
# Implement as an arg, -m? -nametomach? -nametomach not
# ideal because then you can't match -p or -n, +nametomatch?
# [-[n ]]NUM overrides how many to list
# [-p ]pathname overrides pwd to pathname
local lpath="$PWD" # default path
local llen=5 # default NUM
while (( "$#" )); do case "$1" in # parse args
-p) [ -n "$2" ] && # set path
lpath="$2" && shift; shift;;
-+([0-9])) llen=${1:1}; shift;; # set NUM
+([0-9])) llen=${1}; shift;; # set NUM
-n) llen="$2"; shift 2;; # set NUM
-n+([0-9])) llen=${1:2}; shift;; # set NUM
--) shift; break;; # end parsing
*) if [ -d "$1" ]; then # default
lpath="$1"; shift # check if a path
else
echo "Usage:> lstr [[-[n ]]NUM] [[-p ]pathname]"
echo "Arg not supported: $1"; return 1
fi;;
esac; done
ls -lhtr "$lpath" | tail -$llen
}
vio(){
# vim -O shorthand, if only 1 arg open same file twice
if [ "$#" -lt 2 ]; then
vim -O "$1" "$1"
else
vim -O "$@"
fi
}
ptop(){
# run (h)top on pgrep output (only this $USER)
[ -z "$1" ] &&\
echo 'Usage:> ptop <pgrep_str>' && return 1
local plist=''; local lis=''
while [ "$#" -gt 0 ]; do
lis="$(pgrep -u $USER -f "$1")"
[ -n "$lis" ] &&\
plist="$plist\n$lis"
shift
done
plist="$(echo -ne "${plist:2}" |tr '\n' ',')"
if [ -n "$plist" ]; then
if htop --version &>/dev/null; then
htop -p$plist
else
top -p$plist
fi; fi
}
if xdotool --version &>/dev/null; then
click2top(){
# click a window to open it in (h)top
echo 'Select window to open in top ...'
local scinf="$(xwininfo |awk '/Window id:/ {print $4}')"
scinf=$(xdotool getwindowpid $scinf)
if htop --version &>/dev/null; then
# NB: Hit 'H' in htop to not show other threads of parent process
htop -p $scinf
else
top -p $scinf
fi
}
fi
pwxtot(){
# total energy for pw.x output file
local ofil='scf.out'
[ -n "$1" ] && ofil="$1"
grep '! total energy' $ofil |tail -1 |cut -b34-49
}
colsum(){
# 1-based column indexing
# arg1 = col number
# arg2 = file name
awk "{sum+=\$$1} END {print sum}" "$2"
}
aunits(){
# atmoic units conversion
# handles bohr and angstrom since the available `units` package does not.
# arg1 : value to convert
# arg2 : input units
# arg3 : output units
b2a='0.52917721067'
if [ "$2" = 'bohr' ] && [ "$3" = 'ang' ]; then
ret="$(echo "$1 * $b2a" |bc -l)"
elif [ "$3" = 'bohr' ] && [ "$2" = 'ang' ]; then
ret="$(echo "$1 / $b2a" |bc -l)"
else
printf 'Usage:> aunits <value> <units_in> <units_out>\n'
return 1
fi
printf '%-15.8g\n' "$ret" # left justify
}
b2a(){ aunits $1 bohr ang; } # bohr to ang shorthand
a2b(){ aunits $1 ang bohr; } # ang to bohr shorthand
gitlines(){
# show how many lines were changed between commits and include all
# changes from commits in between
if [ "$#" -lt 2 ]; then
echo 'Usage:> gitlines <commit1> <commit2> [author]'
return 1
fi
if [ "$#" -eq 2 ]; then
git log --numstat --pretty="%H" $1..$2 |\
awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'
else
git log --numstat --pretty="%H" --author="$3" $1..$2 |\
awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'
fi
}
sshkex(){
# ssh key exchange
if [ -z "$1" ]; then
echo 'Usage:> sshkex <user@host>'; return 1; fi
if [ -s $HOME/.ssh/id_rsa.pub ]; then
cat $HOME/.ssh/id_rsa.pub |\
ssh $1 'mkdir -p .ssh; cat >> .ssh/authorized_keys'
else
echo 'No public key found, run: ssh-keygen -t rsa'
fi
}
# ______________________________________________________________________
# / \
# ( PS1 setting )
# \______________________________________________________________________/
#
# Leave this is for 'basic' PS1 to still be set
case "$TERM" in xterm-color|*-256color) color_prompt=yes;; esac
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
[ "$color_prompt" = yes ] ||\
PS1='\u@\h:\w\$ '
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;\u@\h: \w\a\]$PS1";; *);; esac
if [ ! -f $HOME/x1ps1.sh ]; then # source from github
echo "Pulling x1ps1 from online"
curl -L -o $HOME/x1ps1.sh http://psisq.co/x1ps1 &>/dev/null
#wget -O $HOME/x1ps1.sh http://psisq.co/x1ps1 &>/dev/null
fi
# make sure successfull + opt out with 'basic' arg
if [ "$PS1_OPTS" != "basic" ] && [ -f $HOME/x1ps1.sh ]; then
. $HOME/x1ps1.sh
#export GIT_PS1_SHOWCOLORHINTS=true
#export GIT_PS1_SHOWDIRTYSTATE=true
#PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
fi
# ______________________________________________________________________
# / \
# ( Machine specific )
# \______________________________________________________________________/
#
## Environment vars
export QEDIR="$HOME/opt/gitlab-q-e" # Quantum Espresso root dir
# PATH setter, accounts for double sourcing .bashrc
case "$PATH" in *"$QEDIR"*) ;;
*) export PATH="$QEDIR/bin:$HOME/bin:$PATH";;
esac
## Aliases
alias cdpw="cd $QEDIR/PW/src"
alias cdpp="cd $QEDIR/PP/src"
alias cdmod="cd $QEDIR/Modules"
alias cdcw="cd $CURRWORK"
## Last line to set window title
[ "$PS1_OPTS" != "basic" ] && [ -f $HOME/x1ps1.sh ] &&\
#set window title
[ -n "$HOSTNAME" ] && \
echo -ne "\e];fresh term @$HOSTNAME\007" || \
echo -ne "\e];fresh term\007"
#(EOF)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment