From: Ian Kelling Date: Tue, 12 Jul 2016 17:19:40 +0000 (-0700) Subject: lots of updates, and sort my bash functions X-Git-Url: https://iankelling.org/git/?p=distro-setup;a=commitdiff_plain;h=42a4311f54f498110a548c56a84461ffba00641a lots of updates, and sort my bash functions --- diff --git a/.bashrc b/.bashrc index 118a9cc..b906d2e 100644 --- a/.bashrc +++ b/.bashrc @@ -52,6 +52,8 @@ fi CDPATH=. +set -o pipefail + # remove all aliases. aliases provided by the system tend to get in the way, # for example, error happens if I try to define a function the same name as an alias unalias -a @@ -172,76 +174,51 @@ C_DEFAULT_DIR=/a ## include files ### ################### -for _x in /a/bin/distro-functions/src/* /a/bin/bash-programs-by-ian/repos/*/*-function; do +for _x in /a/bin/distro-functions/src/* /a/bin/*/*-function; do source "$_x" done unset _x -source /a/bin/semi-private # so I can share my bashrc +# so I can share my bashrc +for x in /a/bin/bash_unpublished/*; do source $x; done source $(dirname $(readlink -f $BASH_SOURCE))/path_add-function +source /a/bin/log-quiet/logq-function +path_add /a/exe path_add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-tools # todo, these need to be renamed to be less generic. # sync overrode something else useful #path_add $HOME/bin/bash-programs-by-ian/utils -[[ -e $HOME/mw_vars ]] && source $HOME/mw_vars ############### ### aliases ### ############### -# disabled for now, but these are generally good -# if [[ $- == *i* ]]; then -# alias cp='cp -i' -# alias mv='mv -i' -# fi - -# remove any default aliases for these -alias ls > /dev/null 2>&1 && unalias ls -alias ll > /dev/null 2>&1 && unalias ll -alias grep > /dev/null 2>&1 && unalias grep - +# very few aliases, functions are always preferred. -mkdir() { - command mkdir -p "$@" -} +# ancient stuff. +if [[ $OS == Windows_NT ]]; then + alias ffs='cygstart "/c/Program Files (x86)/Mozilla Firefox/firefox.exe" -P scratch' + export DISPLAY=nt + alias j='command cygpath' + alias t='command cygstart' + alias cygstart='echo be quick, use the alias "t" instead :\)' + alias cygpath='echo be quick, use the alias "j" instead :\)' +fi -alias d='builtin bg' -complete -A stopped -P '"%' -S '"' d -alias hi='history' +# keep this in mind? good for safety. +# alias cp='cp -i' +# alias mv='mv -i' -# 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. +# remove any default aliases for these +unalias ls ll grep &>/dev/null ||: -# 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 -s() { - if [[ $EUID != 0 || $1 == -* ]]; then - SUDOD="$PWD" sudo -i "$@" - else - "$@" - fi -} -if [[ $OS == Windows_NT ]]; then - alias ffs='cygstart "/c/Program Files (x86)/Mozilla Firefox/firefox.exe" -P scratch' - export DISPLAY=nt - alias j='command cygpath' - alias t='command cygstart' - alias cygstart='echo be quick, use the alias "t" instead :\)' - alias cygpath='echo be quick, use the alias "j" instead :\)' -fi @@ -252,130 +229,115 @@ fi ##################### -sdf() { - c /sdx/test/sandbox/ -} +mkdir() { command mkdir -p "$@"; } -debian_pick_mirror () { - # netselect-apt finds a fast mirror. - # but we need to replace the mirrors ourselves, - # because it doesn't do that. best it can do is - # output a basic sources file - # here we get the server it found, get the main server we use - # then substitute all instances of one for the other in the sources file - # and backup original to /etc/apt/sources.list-original. - # this is idempotent. the only way to identify debian sources is to - # note the original server, so we put it in a comment so we can - # identify it later. - local file=$(mktemp -d)/f # safe way to get file name without creating one - sudo netselect-apt -o "$file" || return 1 - url=$(grep ^\\w $file | head -n1 | awk '{print $2}') - sudo cp -f /etc/apt/sources.list /etc/apt/sources.list-original - sudo sed -ri "/http.us.debian.org/ s@( *[^ #]+ +)[^ ]+([^#]+).*@\1$url\2# http.us.debian.org@" /etc/apt/sources.list - sudo apt-get update +# fast commit all +ic() { + git commit -am "$*" } -a() { - beet "${@}" +# file cut copy and paste, like the text buffers :) +# I havn't tested these. +_fbufferinit() { # internal use by + ! [[ $my_f_tempdir ]] && my_f_tempdir=$(mktemp -d) + rm -rf "$my_f_tempdir"/* } - -dus() { - du -sh ${@:-*} | sort -h +fcp() { # file cp + _fbufferinit + cp "$@" "$my_f_tempdir"/ } - -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 +fct() { # file cut + _fbufferinit + mv "$@" "$my_f_tempdir"/ +} +fpst() { # file paste + [[ $2 ]] && { echo too many arguments; return 1; } + target=${1:-.} + cp "$my_f_tempdir"/* "$target" } -ccat () { # config cat. see a config without extra lines. - grep '^\s*[^[:space:]#]' "$@" +# history search +k() { grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 40; } + +# horizontal row. used to break up output +hr() { printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq $COLUMNS); } + + +# insensitive find +ifn () { + find -L . -iname "*$**" 2>/dev/null } +# test existence / exists +te() { + local ret=0 + for x in "$@"; do + [[ -e "$x" || -L "$x" ]] || ret=1 + done + return $ret +} -if type ack-grep >/dev/null 2>&1; then - alias ack=ack-grep -fi +# todo, update this +complete -F _longopt la lower low rlt rld rl lld ts ll dircp ex fcp fct fpst gr -postconfin() { - local MAPFILE - mapfile -t - local s - [[ $EUID == 0 ]] || s=s - $s postconf -ev "${MAPFILE[@]}" +# use sb instead of s is for sudo redirections, eg. sb 'echo "ok fine" > /etc/file' +sb() { + local SUDOD="$PWD" + sudo -i bash -c "$@" } +complete -F _root_command s sb -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) +_cdiff-prep() { + # join options which are continued to multiples lines onto one line + local first=true + grep -vE '^([ \t]*#|^[ \t]*$)' "$1" | while IFS= read -r line; do + # remove leading spaces/tabs. assumes extglob + if [[ $line == "[ ]*" ]]; then + line="${line##+( )}" fi - echo -en "\r" - echo -n "$d" - for ((i=0; i> "$2" + pastline="$line" else - x=$((x+1)) + pastline="$pastline $line" fi - sleep 5 done + echo "$pastline" >> "$2" } -gr() { - grep -iIP --color=auto "$@" +_khfix_common() { + local h=${1##*@} + ssh-keygen -R $h + local x=$(timeout 0.1 ssh -v $1 |& sed -rn "s/debug1: Connecting to $h \[([^\]*)].*/\1/p"); + ssh-keygen -R $x } - -grr() { - if [[ ${#@} == 1 ]]; then - grep -riIP --color=auto "$@" . - else - grep -riIP --color=auto "$@" - fi +khfix() { # known hosts fix + _khfix_common "$@" + ssh $1 : } - -pub() { - rld /a/h/_site/ li:/var/www/iankelling.org/public_html +khcopy() { + _khfix_common "$@" + ssh-copy-id $1 } -mkc() { - mkdir "$1" - c "$1" +a() { + beet "${@}" } +ack() { ack-grep "$@"; } + bashrcpush () { local startdir="$PWD" cd ~ for x in "$@"; do ssh $x mkdir -p bin/distro-functions/src - tar cz bin/bash-programs-by-ian bin/semi-private bin/distro-functions/src | ssh $x tar xz + tar cz bin/semi-private bin/distro-functions/src | ssh $x tar xz done cd $(mktemp -d) command cp /a/c/repos/bash/!(.git) ~/.gitconfig . @@ -385,14 +347,7 @@ bashrcpush () { cd "$startdir" } -virshrm() { - for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done -} - -whatismyip() { curl ipecho.net/plain ; echo; } - -# history search -k() { grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 40; } +caa() { git commit --amend --no-edit -a; } calc() { echo "scale=3; $*" | bc -l; } # no having to type quotes, but also no command history: @@ -402,17 +357,23 @@ clc() { echo "scale=3; $x" | bc -l } -# diff config files, -# setup for format of postfix -# option = stuff[,] -# [more stuff] -cdiff() { +cam() { + git commit -am "$*" +} + +ccat () { # config cat. see a config without extra lines. + grep '^\s*[^[:space:]#]' "$@" +} +cdiff() { + # diff config files, + # setup for format of postfix, eg: + # option = stuff[,] + # [more stuff] local pastline local unified="$(mktemp)" local f1="$(mktemp)" local f2="$(mktemp)" - _cdiff-prep "$1" "$f1" _cdiff-prep "$2" "$f2" cat "$f1" "$f2" | grep -Po '^[^=]+=' | sort | uniq > "$unified" @@ -422,56 +383,6 @@ cdiff() { done < "$unified" } -cim() { - git commit -m "$*" -} - -cam() { - git commit -am "$*" -} - -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 "$@" -} - -# join options which are continued to multiples lines onto one line -_cdiff-prep() { - local first=true - grep -vE '^([ \t]*#|^[ \t]*$)' "$1" | while IFS= read -r line; do - # remove leading spaces/tabs. assumes extglob - if [[ $line == "[ ]*" ]]; then - line="${line##+( )}" - fi - if $first; then - pastline="$line" - first=false - elif [[ $line == *=* ]]; then - echo "$pastline" >> "$2" - pastline="$line" - else - pastline="$pastline $line" - fi - done - echo "$pastline" >> "$2" -} - -# makes it so chown -R symlink affects the symlink and its target. -chown() { - if [[ $1 == -R ]]; then - shift - command chown -h "$@" - command chown "$@" - command chown -RH "$@" - else - command chown "$@" - fi -} - - - cgpl () { if [[ $# == 0 ]]; then @@ -481,210 +392,121 @@ cgpl () fi } - -dc() { - diff --strip-trailing-cr -w "$@" # diff content +chown() { + # makes it so chown -R symlink affects the symlink and its target. + if [[ $1 == -R ]]; then + shift + command chown -h "$@" + command chown "$@" + command chown -RH "$@" + else + command chown "$@" + fi } - -dt() { - date "+%A, %B %d, %r" "$@" +cim() { + git commit -m "$*" } +d() { builtin bg; } +complete -A stopped -P '"%' -S '"' d -e() { echo "$@"; } - - -envload() { # load environment from a previous: export > file - local file=${1:-$HOME/.${USER}_env} - eval "$(export | sed 's/^declare -x/export -n/')" - while IFS= read -r line; do - # declare -x makes variables local to a function - eval ${line/#declare -x/export} - done < "$file" -} - - - -# havn't tested these: -#file cut copy and paste, like the text buffers :) -_fbufferinit() { # internal use by - ! [[ $my_f_tempdir ]] && my_f_tempdir=$(mktemp -d) - rm -rf "$my_f_tempdir"/* -} -fcp() { # file cp - _fbufferinit - cp "$@" "$my_f_tempdir"/ -} -fct() { # file cut - _fbufferinit - mv "$@" "$my_f_tempdir"/ +dat() { # do all tee, for more complex scripts + tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l) } -fpst() { # file paste - [[ $2 ]] && { echo too many arguments; return 1; } - target=${1:-.} - cp "$my_f_tempdir"/* "$target" +da() { # do all + local host + "$@" + for host in x2 tp treetowl; do + ssh $host "$@" + done } - -# find array. make an array of file names found by find into $x -# argument: find arguments -# return: find results in an array $x -fa() { - while read -rd ''; do - x+=("$REPLY"); - done < <(find "$@" -print0); +dc() { + diff --strip-trailing-cr -w "$@" # diff content } - -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 +debian_pick_mirror () { + # netselect-apt finds a fast mirror. + # but we need to replace the mirrors ourselves, + # because it doesn't do that. best it can do is + # output a basic sources file + # here we get the server it found, get the main server we use + # then substitute all instances of one for the other in the sources file + # and backup original to /etc/apt/sources.list-original. + # this is idempotent. the only way to identify debian sources is to + # note the original server, so we put it in a comment so we can + # identify it later. + local file=$(mktemp -d)/f # safe way to get file name without creating one + sudo netselect-apt -o "$file" || return 1 + url=$(grep ^\\w $file | head -n1 | awk '{print $2}') + sudo cp -f /etc/apt/sources.list /etc/apt/sources.list-original + sudo sed -ri "/http.us.debian.org/ s@( *[^ #]+ +)[^ ]+([^#]+).*@\1$url\2# http.us.debian.org@" /etc/apt/sources.list + sudo apt-get update } - -ff() { - if type -P firefox &>/dev/null; then - firefox "$@" - else - iceweasel "$@" - fi +despace() { + local x y + for x in "$@"; do + y="${x// /_}" + safe_rename "$x" "$y" + done } -fw() { - firefox -P default "$@" >/dev/null 2>&1 +dt() { + date "+%A, %B %d, %r" "$@" } -fn() { - firefox -P alt "$@" >/dev/null 2>&1 +dus() { + du -sh ${@:-*} | sort -h } +e() { echo "$@"; } -# horizontal row. used to break up output -hr() { printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq $COLUMNS); } - - -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 - -# fast commit all -ic() { - git commit -am "$*" -} - -# insensitive find -ifn () { - find -L . -iname "*$**" 2>/dev/null +ediff() { + [[ ${#@} == 2 ]] || { echo "error: ediff requires 2 arguments"; return 1; } + emacs --eval "(ediff-files \"$1\" \"$2\")" } - - -l() { - if [[ $PWD == /[iap] ]]; then - command ls -A --color=auto -I lost+found "$@" - else - command ls -A --color=auto "$@" - fi +envload() { # load environment from a previous: export > file + local file=${1:-$HOME/.${USER}_env} + eval "$(export | sed 's/^declare -x/export -n/')" + while IFS= read -r line; do + # declare -x makes variables local to a function + eval ${line/#declare -x/export} + done < "$file" } - -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 +fa() { + # find array. make an array of file names found by find into $x + # argument: find arguments + # return: find results in an array $x + while read -rd ''; do + x+=("$REPLY"); + done < <(find "$@" -print0); } -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 -} - -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 +ff() { + if type -P firefox &>/dev/null; then + firefox "$@" + else + iceweasel "$@" fi } -despace() { - local x y - for x in "$@"; do - y="${x// /_}" - safe_rename "$x" "$y" - done -} - - - -# test existence / exists -te() { - local ret=0 - for x in "$@"; do - [[ -e "$x" || -L "$x" ]] || ret=1 - done - return $ret -} - -# show make targets, via http://stackoverflow.com/questions/3063507/list-goals-targets-in-gnu-make -make-targets() { - make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' +fn() { + firefox -P alt "$@" >/dev/null 2>&1 } -# fix root file ownership for FILE argument. -# check if parent or grandparent is not root and if the dir of FILE is also -# owned by that user, and change ownership to that user -perm_fix() { - local parent - if [[ $EUID == 0 ]]; then - te "$1" || touch "$1" - if [[ $(stat -c "%u" "$1") == 0 ]] ; then - argdir=$(dirname "$1") - if [[ $(stat -c "%u" "$argdir") != 0 ]] ; then - if ! chown "--reference=$argdir" "$1"; then - echo failed to fix bad ownership file permissons - return 1 - fi - fi - fi - fi -} - -# see notes for usage fsdiff () { local missing=false local dname="${PWD##*/}" @@ -709,8 +531,11 @@ fsdiff () { (( msize <= 100 )) && cat $m fi } - fsdiff-test() { + # expected output, with different tmp dirs + # /tmp/tmp.HDPbwMqdC9/c/d ./c/d + # /a/tmp/tmp.qLDkYxBYPM-missing + # ./b cd $(mktemp -d) echo ok > a echo nok > b @@ -722,16 +547,10 @@ fsdiff-test() { echo ok > $x/a fsdiff $x } -# expected output, with different tmp dirs -# /tmp/tmp.HDPbwMqdC9/c/d ./c/d -# /a/tmp/tmp.qLDkYxBYPM-missing -# ./b - - -# test whether missing files were renamed, generally for use with fsdiff -# $1 = fsdiff output file, $2 = directory to compare to. pwd = fsdiff dir -# echos non-renamed files rename-test() { + # test whether missing files were renamed, generally for use with fsdiff + # $1 = fsdiff output file, $2 = directory to compare to. pwd = fsdiff dir + # echos non-renamed files local x y found unset sums for x in "$2"/*; do @@ -752,127 +571,76 @@ rename-test() { } -# get a random string -#par2rbase=$(head -c 50 /dev/urandom | tr -cd '[:alpha:]') -par2r() { - [[ $par2rbase ]] || { echo "set \$par2rbase first"; return 1; } - d="$PWD" - for x in **; do - if [[ -d $x ]]; then - cd "$x" - par2 c QDLDeDJ6z4.par2 * - cd "$d" - fi - done - +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 } -md5diff() { - [[ $(md5sum < "$1") != $(md5sum < "$2") ]] + +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 +} -pfind() { #find *$1* in $PATH - [[ $# != 1 ]] && { echo requires 1 argument; return 1; } - local pathArray - IFS=: pathArray=($PATH); unset IFS - find "${pathArray[@]}" -iname "*$1*" +gr() { + grep -iIP --color=auto "$@" } -# do pwd + some other info. -#pwd() { echo "$(ll -d "$PWD") $USER@$HOSTNAME $(date +%r)"; } -q() { # start / launch a program in the backround and redir output to null - "$@" &> /dev/null & -} -pwgen() { - apg -s -m 10 -x 14 -t -} -r() { - exit "$@" 2>/dev/null -} -# connect to vms made with virt-install -vspicy() { - spicy -p $(sudo virsh dumpxml "$1"|grep " $max_lines)); then + prune_lines=$(($linecount - $max_lines)) + head -n $prune_lines "$HISTFILE" >> "$harchive" \ + && sed -ie "1,${prune_lines}d" $HISTFILE fi - # rync options are without -g for group - s rsync -rlpthvi$o "${opts[@]}" "$path" "root@$host:$path"; -} - -lcn() { locate -i "*$**"; } - -vpn() { - s systemctl start openvpn@client& - journalctl --unit=openvpn@client -f -n0 -} -vpnoff() { - s systemctl stop openvpn@client } - -complete -F _rsync -o nospace rld rlt fl -# rl without preserving modification time. for some reason I had this as default before. -# perhaps that reason will come up again and I will document it. -rlt() { rsync -ahvic --delete --no-t "$@"; } +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() { @@ -881,43 +649,278 @@ if ! type service &>/dev/null; then } fi -# use sb instead of s is for sudo redirections, eg. sb 'echo "ok fine" > /etc/file' -sb() { - local SUDOD="$PWD" - sudo -i bash -c "$@" -} -complete -F _root_command s sb -# use -ll, less secure but faster. -srm () { - command srm -ll "$@" + + +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 } -# sudo redo. be aware, this command may not work right on strange distros or earlier software -sr() { - if [[ $# == 0 ]]; then - sudo -E bash -c -l "$(history -p '!!')" + +l() { + if [[ $PWD == /[iap] ]]; then + command ls -A --color=auto -I lost+found "$@" else - echo this command redos last history item. no argument is accepted + 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 +} + +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" +} + + +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 +} + +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 + # 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<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 +} + +sdf() { + c /sdx/test/sandbox/ +} + +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 "$@" +} + -# 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 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 ;; + case $option in + l ) arg_base=$logdir ;; t ) do_stamp=true ;; esac done @@ -933,68 +936,73 @@ splay() { # script replay scriptreplay "$1.t" "$1.s" } - -# like -e for functions. returns on error. -# at the end of the function, disable with: -# trap ERR -funce() { - trap 'echo "${BASH_COMMAND:+BASH_COMMAND=\"$BASH_COMMAND\" } -${FUNCNAME:+FUNCNAME=\"$FUNCNAME\" }${LINENO:+LINENO=\"$LINENO\" }\$?=$?" -trap ERR -return' ERR +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 } -# timer in minutes -tm() { - (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 & +srm () { + # with -ll, less secure but faster. + command srm -ll "$@" } -ser() { - local s; [[ $EUID != 0 ]] && s=sudo - if type -p systemctl &>/dev/null; then - $s systemctl $1 $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 - $s service $2 $1 - fi -} - -sgo() { # service go - service=$1 - ser start $service - if type -p systemctl &>/dev/null; then - ser enable $service + rm -rf "$@" fi } -vm-set-listen(){ - local t=$(mktemp) - local vm=$1 - local ip=$2 - s virsh dumpxml $vm | sed -r "s/(' >"$1" - e '#include ' >>"$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 + e '#include ' >"$1" + e '#include ' >>"$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" - + 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" + echo "#!/bin/bash" > "$1" + chmod +x "$1" fi [[ $quiet ]] || g "$1" - } -ediff() { - [[ ${#@} == 2 ]] || { echo "error: ediff requires 2 arguments"; return 1; } - emacs --eval "(ediff-files \"$1\" \"$2\")" + +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 + set +x PROMPT_COMMAND=prompt_command else unset PROMPT_COMMAND PS1="\w \$ " - set -x + set -x fi } - -dat() { # do all tee, for more complex scripts - tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l) +virshrm() { + for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done } -da() { # do all - local host - "$@" - for host in x2 tp treetowl; do - ssh $host "$@" - done +vm-set-listen(){ + local t=$(mktemp) + local vm=$1 + local ip=$2 + s virsh dumpxml $vm | sed -r "s/( $max_lines)); then - prune_lines=$(($linecount - $max_lines)) - head -n $prune_lines "$HISTFILE" >> "$harchive" \ - && sed -ie "1,${prune_lines}d" $HISTFILE - fi +vpn() { + s systemctl start openvpn@client& + journalctl --unit=openvpn@client -f -n0 } -############## work stuff ############# - -rn() { - pushd /sdx/test/sandbox/; - ./setup.sh && ./run.sh - popd +vpnoff() { + s systemctl stop openvpn@client } + vrm() { virsh destroy $1 virsh undefine $1 @@ -1137,8 +1096,20 @@ vrm() { +vspicy() { + # connect to vms made with virt-install + spicy -p $(sudo virsh dumpxml "$1"|grep "