-}
-
-
-funce() {
- # like -e for functions. returns on error.
- # at the end of the function, disable with:
- # trap ERR
- trap 'echo "${BASH_COMMAND:+BASH_COMMAND=\"$BASH_COMMAND\" }
-${FUNCNAME:+FUNCNAME=\"$FUNCNAME\" }${LINENO:+LINENO=\"$LINENO\" }\$?=$?"
-trap ERR
-return' ERR
-}
-
-
-fw() {
- firefox -P default "$@" >/dev/null 2>&1
-}
-
-git_empty_branch() { # start an empty git branch. carefull, it deletes untracked files.
- [[ $# == 1 ]] || { echo 'need a branch name!'; return 1;}
- local gitroot
- gitroot || return 1 # function to set gitroot
- builtin cd "$gitroot"
- git symbolic-ref HEAD refs/heads/$1
- rm .git/index
- git clean -fdx
-}
-
-gr() {
- grep -iIP --color=auto "$@"
-}
-
-
-
-
-
-grr() {
- if [[ ${#@} == 1 ]]; then
- grep -riIP --color=auto "$@" .
- else
- grep -riIP --color=auto "$@"
- fi
-}
-
-hl() { # history limit. Write extra history to archive file.
- # todo: this is not working or not used currently
- local max_lines linecount tempfile prune_lines x
- local harchive="${HISTFILE}_archive"
- for x in "$HISTFILE" "$harchive"; do
- [[ -e $x ]] || { touch "$x" && echo "notice from hl(): creating $x"; }
- if [[ ! $x || ! -e $x || ! -w $x || $(stat -c "%u" "$x") != $EUID ]]; then
- echo "error in hl: history file \$x:$x no good"
- return 1
- fi
- done
- history -a # save history
- max_lines=$HISTFILELINES
- [[ $max_lines =~ ^[0-9]+$ ]] || { echo "error in hl: failed to get max line count"; return 1; }
- linecount=$(wc -l < $HISTFILE) # pipe so it doesn't output a filename
- [[ $linecount =~ ^[0-9]+$ ]] || { echo "error in hl: wc failed"; return 1; }
- if (($linecount > $max_lines)); then
- prune_lines=$(($linecount - $max_lines))
- head -n $prune_lines "$HISTFILE" >> "$harchive" \
- && sed --follow-symlinks -ie "1,${prune_lines}d" $HISTFILE
- fi
-}
-
-hr() { # horizontal row. used to break up output
- printf "$(tput setaf 5)â–ˆ$(tput sgr0)%.0s" $(seq $COLUMNS)
- echo
-}
-
-
-i() { git "$@"; }
-# modified from ~/local/bin/git-completion.bash
-# other completion commands are mostly taken from bash_completion package
-complete -o bashdefault -o default -o nospace -F _git i 2>/dev/null \
- || complete -o default -o nospace -F _git i
-
-if ! type service &>/dev/null; then
- service() {
- echo actually running: systemctl $2 $1
- systemctl $2 $1
- }
-fi
-
-ic() {
- # fast commit all
- git commit -am "$*"
-}
-
-
-ifn () {
- # insensitive find
- find -L . -iname "*$**" 2>/dev/null
-}
-
-
-if [[ $OS == Windows_NT ]]; then
- # cygstart wrapper
- cs() {
- cygstart "$@" &
- }
- xp() {
- explorer.exe .
- }
- # launch
- o() {
- local x=(*$1*)
- (( ${#x[#]} > 1 )) && { echo "warning ${#x[#]} matches found"; sleep 1; }
- cygstart *$1* &
- }
-else
- o() {
- if type gvfs-open &> /dev/null ; then
- gvfs-open "$@"
- else
- xdg-open "$@"
- fi
- # another alternative is run-mailcap
- }
-fi
-
-
-
-istext() {
- grep -Il "" "$@" &>/dev/null
-}
-
-
-l() {
- if [[ $PWD == /[iap] ]]; then
- command ls -A --color=auto -I lost+found "$@"
- else
- command ls -A --color=auto "$@"
- fi
-}
-
-
-lcn() { locate -i "*$**"; }
-
-lld() { ll -d "$@"; }
-
-low() { # make filenames all lowercase
- local x y
- for x in "$@"; do
- y=$(tr "[A-Z]" "[a-z]" <<<"$x")
- [[ $y != $x ]] && mv "$x" "$y"
- done
-}
-
-
-
-
-lower() { # make first letter of filenames lowercase.
- local x
- for x in "$@"; do
- if [[ ${x::1} == [A-Z] ]]; then
- y=$(tr "[A-Z]" "[a-z]" <<<"${x::1}")"${x:1}"
- safe_rename "$x" "$y"
- fi
- done
-}
-
-
-k() { # history search
- grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 40;
-}
-
-
-make-targets() {
- # show make targets, via http://stackoverflow.com/questions/3063507/list-goals-targets-in-gnu-make
- make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
-}
-
-
-md5diff() {
- [[ $(md5sum < "$1") != $(md5sum < "$2") ]]
-}
-
-
-
-mkc() {
- mkdir "$1"
- c "$1"
-}
-
-mkdir() { command mkdir -p "$@"; }
-
-pithos() {
- cd /a/opt/Pithosfly/
- python3 -m pithos&r
-}
-
-pakaraoke() {
- # from http://askubuntu.com/questions/456021/remove-vocals-from-mp3-and-get-only-instrumentals
- pactl load-module module-ladspa-sink sink_name=Karaoke master=alsa_output.usb-Audioengine_Audioengine_D1-00.analog-stereo plugin=karaoke_1409 label=karaoke control=-30
-}
-
-
-pfind() { #find *$1* in $PATH
- [[ $# != 1 ]] && { echo requires 1 argument; return 1; }
- local pathArray
- IFS=: pathArray=($PATH); unset IFS
- find "${pathArray[@]}" -iname "*$1*"
-}
-
-pick-trash() {
- # trash-restore lists everything that has been trashed at or below CWD
- # This picks out files just in CWD, not subdirectories,
- # which also match grep $1, usually use $1 for a time string
- # which you get from running restore-trash once first
- local name x ask
- local nth=1
- # last condition is to not ask again for ones we skipped
- while name="$( echo | restore-trash | gr "$PWD/[^/]\+$" | gr "$1" )" \
- && [[ $name ]] && (( $(wc -l <<<"$name") >= nth )); do
- name="$(echo "$name" | head -n $nth | tail -n 1 )"
- read -p "$name [Y/n] " ask
- if [[ ! $ask || $ask == [Yy] ]]; then
- x=$( echo "$name" | gr -o "^\s*[0-9]*" )
- echo $x | restore-trash > /dev/null
- elif [[ $ask == [Nn] ]]; then
- nth=$((nth+1))
- else
- return
- fi
- done
-}
-
-postconfin() {
- local MAPFILE
- mapfile -t
- local s
- [[ $EUID == 0 ]] || s=s
- $s postconf -ev "${MAPFILE[@]}"
-}
-
-pub() {
- rld /a/h/_site/ li:/var/www/iankelling.org/html
-}
-
-pubip() { curl -4s https://icanhazip.com; }
-whatismyip() { pubip; }
-
-
-pwgen() {
- apg -s -m 10 -x 14 -t
-}
-
-
-q() { # start / launch a program in the backround and redir output to null
- "$@" &> /dev/null &
-}
-
-r() {
- exit "$@" 2>/dev/null
-}
-
-rbpipe() { rbt post -o --diff-filename=- "$@"; }
-rbp() { rbt post -o "$@"; }
-
-rl() {
- # rsync, root is required to keep permissions right.
- # rsync --archive --human-readable --verbose --itemize-changes --checksum \(-ahvic\) \
- # --no-times --delete
- # basically, make an exact copy, use checksums instead of file times to be more accurate
- rsync -ahvic --delete "$@"
-}
-rld() {
- # like rlu, but don't delete files on the target end which
- # do not exist on the original end.
- rsync -ahvic "$@"
-}
-complete -F _rsync -o nospace rld rl rlt
-
-rlt() {
- # rl without preserving modification time.
- rsync -ahvic --delete --no-t "$@"
-}
-
-rlu() { # [OPTS] HOST PATH
- # eg rlu -opts frodo testpath
- # useful for selectively sending dirs which have been synced with unison,
- # where the path is the same on both hosts.
- opts=("${@:1:$#-2}") # 1 to last -2
- path="${@:$#}" # last
- host="${@:$#-1:1}" # last -1
- if [[ $path == .* ]]; then echo error: need absolut path; return 1; fi
- # rync here uses checksum instead of time so we don't mess with
- # unison relying on time as much. g is for group, same reason
- # to keep up with unison.
- s rsync -rlpchviog --relative "${opts[@]}" "$path" "root@$host:/";
-}
-
-
-rspicy() { # HOST DOMAIN
- local port=$(ssh $1<<EOF
-sudo virsh dumpxml $2|grep "<graphics.*type='spice'" | \
- sed -rn "s/.*port='([0-9]+).*/\1/p"
-EOF
- )
- if [[ $port ]]; then
- spicy -h $1 -p $port
- else
- echo "error: no port found. check that the domain is running."
- fi
-}
-
-s() {
- # background
- # alias s='SUDOD="$PWD" sudo -i '
- # because this is an alias, and the extra space at the end, it would allow
- # aliases to be used with it. but aliases aren't used in scripts,
- # better to eliminate inconsistencies. Plus, you can't do s=s; $s command
- # with an alias, which I like to do in some functions
- # extra space at the end allows aliases to work
- #
- # note: gksudo is recommended for X apps because it does not set the
- # home directory to the same, and thus apps writing to ~ fuck things up
- # with root owned files.
- #
- if [[ $EUID != 0 || $1 == -* ]]; then
- SUDOD="$PWD" sudo -i "$@"
- else
- "$@"
- fi
-}
-
-safe_rename() {
- if [[ $# != 2 ]]; then
- echo safe_rename error: $# args, need 2 >2
- return 1
- elif [[ $1 != $2 ]]; then
- if [[ -e $2 ]]; then
- echo Cannot rename "$1" to "$2" as it already exists.
- else
- mv "$1" "$2"
- fi
- fi
-}
-
-
-sb() { # sudo bash -c
- # use sb instead of s is for sudo redirections,
- # eg. sb 'echo "ok fine" > /etc/file'
- local SUDOD="$PWD"
- sudo -i bash -c "$@"
-}
-complete -F _root_command s sb
-
-
-ser() {
- local s; [[ $EUID != 0 ]] && s=sudo
- if type -p systemctl &>/dev/null; then
- $s systemctl $1 $2
- else
- $s service $2 $1
- fi
-}
-
-sgo() { # service go
- service=$1
- ser restart $service
- if type -p systemctl &>/dev/null; then
- ser enable $service
- fi
-}
-
-
-shellck() {
- # 2086 = unquoted $var
- # 2046 = unquoted $(cmd)
- # i had -x as an arg, but debian testing(stretch) doesn't support it
- shellcheck -e 2086,2046,2068,2006,2119 "$@"
-}
-
-
-slog() {
- # log with script. timing is $1.t and script is $1.s
- # -l to save to ~/typescripts/
- # -t to add a timestamp to the filenames
- local logdir do_stamp arg_base
- (( $# >= 1 )) || { echo "arguments wrong"; return 1; }
- logdir="/a/dt/"
- do_stamp=false
- while getopts "lt" option
- do
- case $option in
- l ) arg_base=$logdir ;;
- t ) do_stamp=true ;;
- esac
- done
- shift $(($OPTIND - 1))
- arg_base+=$1
- [[ -e $logdir ]] || mkdir -p $logdir
- $do_stamp && arg_base+=$(date +%F.%T%z)
- script -t $arg_base.s 2> $arg_base.t
-}
-splay() { # script replay
- #logRoot="$HOME/typescripts/"
- #scriptreplay "$logRoot$1.t" "$logRoot$1.s"
- scriptreplay "$1.t" "$1.s"
-}
-
-sr() {
- # sudo redo. be aware, this command may not work right on strange distros or earlier software
- if [[ $# == 0 ]]; then
- sudo -E bash -c -l "$(history -p '!!')"
- else
- echo this command redos last history item. no argument is accepted
- fi
-}
-
-srm () {
- # with -ll, less secure but faster.
- command srm -ll "$@"
-}
-
-srun() {
- scp $2 $1:/tmp
- ssh $1 /tmp/${2##*/} "${@:2}"
-}
-
-t() {
- local x
- local -a args
- if type -t trash-put >/dev/null; then
- # skip args that don't exist, or else it's an err
- for x in "$@"; do [[ ! -e $x ]] || args+=("$x"); done
- [[ ! ${args[@]} ]] || trash-put "${args[@]}"
- else
- rm -rf "$@"
- fi
-}
-
-
-tclock() {
- clear
- date +%l:%_M
- len=60
- # this goes to full width
- #len=${1:-$((COLUMNS -7))}
- x=1
- while true; do
- if (( x == len )); then
- end=true
- d="$(date +%l:%_M) "
- else
- end=false
- d=$(date +%l:%M:%_S)
- fi
- echo -en "\r"
- echo -n "$d"
- for ((i=0; i<x; i++)); do
- if (( i % 6 )); then
- echo -n _
- else
- echo -n .
- fi
- done
- if $end; then
- echo
- x=1
- else
- x=$((x+1))
- fi
- sleep 5
- done
-}
-
-
-te() {
- # test existence / exists
- local ret=0
- for x in "$@"; do
- [[ -e "$x" || -L "$x" ]] || ret=1
- done
- return $ret
-}
-
-tm() {
- # timer in minutes
- (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 &
-}
-
-ts() { # start editing a new file
- [[ $# != 1 ]] && echo "I need a filename." && return 1
- local quiet
- if [[ $- != *i* ]]; then
- quiet=true
- fi
- if [[ $1 == *.c ]]; then
- e '#include <stdio.h>' >"$1"
- e '#include <stdlib.h>' >>"$1"
- e 'int main(int argc, char * argv[]) {' >>"$1"
- e ' printf( "hello world\n");' >>"$1"
- e ' return 0;' >>"$1"
- e '}' >>"$1"
- e "${1%.c}: $1" > Makefile
- e " g++ -ggdb -std=gnu99 -o ${1%.c} $<" >> Makefile
- e "#!/bin/bash" >run.sh
- e "./${1%.c}" >>run.sh
- chmod +x run.sh
- elif [[ $1 == *.java ]]; then
- e "public class ${1%.*} {" >"$1"
- e ' public static void main(String[] args) {' >>"$1"
- e ' System.out.println("Hello, world!");' >>"$1"
- e ' }' >>"$1"
- e '}' >>"$1"
- else
- echo "#!/bin/bash" > "$1"
- chmod +x "$1"
- fi
- [[ $quiet ]] || g "$1"
-}
-
-
-tu() {
- local s;
- local dir="$(dirname "$1")"
- if [[ -e $1 && ! -w $1 || ! -w $(dirname "$1") ]]; then
- s=s;
- fi
- $s teeu "$@"
-}
-
-tx() { # toggle set -x, and the prompt so it doesn't spam
- if [[ $- == *x* ]]; then
- set +x
- PROMPT_COMMAND=prompt_command
- else
- unset PROMPT_COMMAND
- PS1="\w \$ "
- set -x
- fi
-}
-
-vc() {
- [[ $1 ]] || { e "$0: error, expected cmd to run"; return 1; }
- # manually run vpn so it stays within a network namespace,
- # until I get it all wired up with systemd.
- newns vpn start
- pid=$(< /run/openvpn/client.pid)
- if [[ ! $pid ]]; then
- s ip netns exec vpn /usr/sbin/openvpn --daemon ovpn --config /etc/openvpn/client.conf --cd /etc/openvpn --writepid /run/openvpn/client.pid
- elif [[ ! -e /proc/$pid ]]; then
- echo "$0: ERROR: pidfile pid $pid is not a process!!!"
- return 1
- fi
- gksudo -- ip netns exec vpn gksudo -u ${SUDO_USER:-$USER} "$@"
-}
-
-transmission() {
- vc transmission-gtk&
- i=0
- while ((i < 10)); do
- tun_ip=$(s ip netns exec vpn ip a show dev tun0 | sed -rn 's/^ *inet (10\.8\.\S+).*/\1/p')
- [[ ! $tun_ip ]] || break
- sleep 1
- done
- echo "$0: tun_ip=$tun_ip"
- [[ $tun_ip ]] || { e "$0: error: no tun0 addr found"; return 1; }
- ssh dopub bash <<EOF
-rule="-A PREROUTING -i eth0 -p tcp -m tcp --dport 63324 -j DNAT --to-destination $tun_ip:63324"
-found=false
-while read -r line; do
- if [[ \$line == \$rule ]] && ! \$found; then
- found=true
- else
- iptables -t nat -D \${line#-A}
- fi
-done < <(iptables -t nat -S | grep -E -- '--dport\s+63324')
-\$found || iptables -t nat \$rule
-EOF
-}
-
-virshrm() {
- for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done
-}
-
-vm-set-listen(){
- local t=$(mktemp)
- local vm=$1
- local ip=$2
- s virsh dumpxml $vm | sed -r "s/(<listen.*address=')([^']+)/\1$ip/" | \
- sed -r "s/listen='[^']+/listen='$ip/"> $t
- s virsh undefine $vm
- s virsh define $t
-}
-
-
-vmshare() {
- vm-set-listen $1 0.0.0.0
-}
-
-
-vmunshare() {
- vm-set-listen $1 127.0.0.1
-}
-
-vpn() {
- s systemctl start openvpn@client&
- journalctl --unit=openvpn@client -f -n0
-}
-
-
-vpnoff() {
- s systemctl stop openvpn@client
-}
-
-
-vrm() {
- virsh destroy $1
- virsh undefine $1
-}
-
-
-
-vspicy() {
- # connect to vms made with virt-install
- spicy -p $(sudo virsh dumpxml "$1"|grep "<graphics.*type='spice'"|\
- sed -r "s/.*port='([0-9]+).*/\1/")
-}
-
-
-whatismyip() { curl ipecho.net/plain ; echo; }
-
-
-#############################
-######### misc stuff ########
-#############################
-
-if [[ $- == *i* ]]; then
- # commands to run when bash exits normally
- trap "hl; _smh" EXIT
-fi
-
-
-# temporary variables to test colorization
-# some copied from gentoo /etc/bash/bashrc,
-use_color=false
-# dircolors --print-database uses its own built-in database
-# instead of using /etc/DIR_COLORS. Try to use the external file
-# first to take advantage of user additions.
-safe_term=${TERM//[^[:alnum:]]/?} # sanitize TERM
-match_lhs=""
-[[ -f ~/.dir_colors ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
-[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
-[[ -z ${match_lhs} ]] \
- && type -P dircolors >/dev/null \
- && match_lhs=$(dircolors --print-database)
-# test if our $TERM is in the TERM values in dircolor
-[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true
-
-
-if ${use_color} && [[ $- == *i* ]]; then
-
- if [[ $XTERM_VERSION == Cygwin* ]]; then
- get_term_color() {
- for x in "$@"; do
- case $x in
- underl) echo -n $'\E[4m' ;;
- bold) echo -n $'\E[1m' ;;
- red) echo -n $'\E[31m' ;;
- green) echo -n $'\E[32m' ;;
- blue) echo -n $'\E[34m' ;;
- cyan) echo -n $'\E[36m' ;;
- yellow) echo -n $'\E[33m' ;;
- purple) echo -n $'\E[35m' ;;
- nocolor) echo -n $'\E(B\E[m' ;;
- esac
- done
- }
-
- else
- get_term_color() {
- for x in "$@"; do
- case $x in
- underl) echo -n $(tput smul) ;;
- bold) echo -n $(tput bold) ;;
- red) echo -n $(tput setaf 1) ;;
- green) echo -n $(tput setaf 2) ;;
- blue) echo -n $(tput setaf 4) ;;
- cyan) echo -n $(tput setaf 6) ;;
- yellow) echo -n $(tput setaf 3) ;;
- purple) echo -n $(tput setaf 5) ;;
- nocolor) echo -n $(tput sgr0) ;; # no font attributes
- esac
- done
- }
- fi