From: Ian Kelling Date: Sat, 10 Mar 2018 17:06:02 +0000 (-0500) Subject: various fixes and improvements X-Git-Url: https://iankelling.org/git/?p=distro-setup;a=commitdiff_plain;h=f0a35267f28e274ef3c2f63ffc20a26ca864e37c various fixes and improvements --- diff --git a/.hunspell_en_US b/.hunspell_en_US index d1aa599..90cdb95 100644 --- a/.hunspell_en_US +++ b/.hunspell_en_US @@ -1,2 +1,6 @@ timestamp mediawiki +repo +freenode +sysadmins +nonfree diff --git a/brc b/brc index a4c0589..9ec776d 100644 --- a/brc +++ b/brc @@ -48,7 +48,7 @@ shopt -s no_empty_cmd_completion # http://bash-completion.alioth.debian.org/ # might be sourced by the system already, but I've noticed it not being sourced before if ! type _init_completion &> /dev/null && [[ -r "/usr/share/bash-completion/bash_completion" ]]; then - . /usr/share/bash-completion/bash_completion + . /usr/share/bash-completion/bash_completion fi @@ -66,68 +66,68 @@ shopt -s globstar # inside emcas fixes if [[ $RLC_INSIDE_EMACS ]]; then - # EMACS is used by bash on startup, but we don't need it anymore. - # plus I hit a bug in a makefile which inherited it - unset EMACS - export RLC_INSIDE_EMACS - export PAGER=cat - export MANPAGER=cat - # scp completion does not work, but this doesn't fix it. todo, figure this out - complete -r scp &> /dev/null - # todo, remote file completion fails, figure out how to turn it off - export NODE_DISABLE_COLORS=1 - # This get's rid of ugly terminal escape chars in node repl - # sometime, I'd like to have completion working in emacs shell for node - # the offending chars can be found in lib/readline.js, - # things that do like: - # stream.write('\x1b[' + (x + 1) + 'G'); - # We can remove them and keep readline, for example by doing this - # to start a repl: - #!/usr/bin/env nodejs - # var readline = require('readline'); - # readline.cursorTo = function(a,b,c) {}; - # readline.clearScreenDown = function(a) {}; - # const repl = require('repl'); - # var replServer = repl.start(''); - # - # no prompt, or else readline complete seems to be confused, based - # on our column being different? node probably needs to send - # different kind of escape sequence that is not ugly. Anyways, - # completion doesn't work yet even with the ugly prompt, so whatever - # - export NODE_NO_READLINE=1 + # EMACS is used by bash on startup, but we don't need it anymore. + # plus I hit a bug in a makefile which inherited it + unset EMACS + export RLC_INSIDE_EMACS + export PAGER=cat + export MANPAGER=cat + # scp completion does not work, but this doesn't fix it. todo, figure this out + complete -r scp &> /dev/null + # todo, remote file completion fails, figure out how to turn it off + export NODE_DISABLE_COLORS=1 + # This get's rid of ugly terminal escape chars in node repl + # sometime, I'd like to have completion working in emacs shell for node + # the offending chars can be found in lib/readline.js, + # things that do like: + # stream.write('\x1b[' + (x + 1) + 'G'); + # We can remove them and keep readline, for example by doing this + # to start a repl: + #!/usr/bin/env nodejs + # var readline = require('readline'); + # readline.cursorTo = function(a,b,c) {}; + # readline.clearScreenDown = function(a) {}; + # const repl = require('repl'); + # var replServer = repl.start(''); + # + # no prompt, or else readline complete seems to be confused, based + # on our column being different? node probably needs to send + # different kind of escape sequence that is not ugly. Anyways, + # completion doesn't work yet even with the ugly prompt, so whatever + # + export NODE_NO_READLINE=1 fi if [[ $- == *i* ]]; then - # for readline-complete.el - if [[ $RLC_INSIDE_EMACS ]]; then - # all for readline-complete.el - stty echo - bind 'set horizontal-scroll-mode on' - bind 'set print-completions-horizontally on' - bind '"\C-i": self-insert' + # for readline-complete.el + if [[ $RLC_INSIDE_EMACS ]]; then + # all for readline-complete.el + stty echo + bind 'set horizontal-scroll-mode on' + bind 'set print-completions-horizontally on' + bind '"\C-i": self-insert' + else + # sakura == xterm-256color + # konsole == xterm + if [[ $TERM == "xterm" ]]; then + # control + arrow keys. for other terminals, see http://unix.stackexchange.com/questions/10806/how-to-change-previous-next-word-shortcut-in-bash + bind '"\e[1;5C": shell-forward-word' 2>/dev/null + bind '"\e[1;5D": shell-backward-word' 2>/dev/null else - # sakura == xterm-256color - # konsole == xterm - if [[ $TERM == "xterm" ]]; then - # control + arrow keys. for other terminals, see http://unix.stackexchange.com/questions/10806/how-to-change-previous-next-word-shortcut-in-bash - bind '"\e[1;5C": shell-forward-word' 2>/dev/null - bind '"\e[1;5D": shell-backward-word' 2>/dev/null - else - # make ctrl-backspace work. for konsole, i fixed it through -# /home/iank/.local/share/konsole/default.keytab - stty werase '^h' - bind '"\eOc": shell-forward-word' - bind '"\eOd": shell-backward-word' - fi - # i can't remember why i did this, probably to free up some keys to bind - # to other things in bash. - # other than C-c and C-z, the rest defined by stty -a are, at least in - # gnome-terminal, overridden by bash, or disabled by the system - stty lnext undef stop undef start undef + # make ctrl-backspace work. for konsole, i fixed it through + # /home/iank/.local/share/konsole/default.keytab + stty werase '^h' + bind '"\eOc": shell-forward-word' + bind '"\eOd": shell-backward-word' fi + # i can't remember why i did this, probably to free up some keys to bind + # to other things in bash. + # other than C-c and C-z, the rest defined by stty -a are, at least in + # gnome-terminal, overridden by bash, or disabled by the system + stty lnext undef stop undef start undef + fi fi @@ -167,7 +167,7 @@ C_DEFAULT_DIR=/a ## include files ### ################### for _x in /a/bin/distro-functions/src/* /a/bin/!(githtml)/*-function?(s); do - source "$_x" + source "$_x" done unset _x # so I can share my bashrc @@ -190,12 +190,12 @@ if [[ -e $_x ]]; then source $_x; fi # 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 :\)' + 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 @@ -231,21 +231,21 @@ unalias ls ll grep &>/dev/null ||: # 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"/* + ! [[ $my_f_tempdir ]] && my_f_tempdir=$(mktemp -d) + rm -rf "$my_f_tempdir"/* } fcp() { # file cp - _fbufferinit - cp "$@" "$my_f_tempdir"/ + _fbufferinit + cp "$@" "$my_f_tempdir"/ } fct() { # file cut - _fbufferinit - mv "$@" "$my_f_tempdir"/ + _fbufferinit + mv "$@" "$my_f_tempdir"/ } fpst() { # file paste - [[ $2 ]] && { echo too many arguments; return 1; } - target=${1:-.} - cp "$my_f_tempdir"/* "$target" + [[ $2 ]] && { echo too many arguments; return 1; } + target=${1:-.} + cp "$my_f_tempdir"/* "$target" } @@ -254,268 +254,268 @@ complete -F _longopt la lower low rlt rld rl lld ts ll dircp ex fcp fct fpst gr _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 - if $first; then - pastline="$line" - first=false - elif [[ $line == *=* ]]; then - echo "$pastline" >> "$2" - pastline="$line" - else - pastline="$pastline $line" - fi - done - echo "$pastline" >> "$2" + # 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 + if $first; then + pastline="$line" + first=false + elif [[ $line == *=* ]]; then + echo "$pastline" >> "$2" + pastline="$line" + else + pastline="$pastline $line" + fi + done + echo "$pastline" >> "$2" } _khfix_common() { - local h=${1##*@} - local x - ssh-keygen -R $h -f $(readlink -f ~/.ssh/known_hosts) - x=$(timeout 1 ssh -oBatchMode=yes -oControlMaster=no -oControlPath=/ -v $1 |& sed -rn "s/debug1: Connecting to $h \[([^\]*)].*/\1/p") - if [[ ! $x ]]; then - echo "khfix: ssh failed" - return 1 - fi - echo "khfix: removing key for $x" - ssh-keygen -R $x -f $(readlink -f ~/.ssh/known_hosts) + local h=${1##*@} + local x + ssh-keygen -R $h -f $(readlink -f ~/.ssh/known_hosts) + x=$(timeout 1 ssh -oBatchMode=yes -oControlMaster=no -oControlPath=/ -v $1 |& sed -rn "s/debug1: Connecting to $h \[([^\]*)].*/\1/p") + if [[ ! $x ]]; then + echo "khfix: ssh failed" + return 1 + fi + echo "khfix: removing key for $x" + ssh-keygen -R $x -f $(readlink -f ~/.ssh/known_hosts) } khfix() { # known hosts fix - _khfix_common "$@" || return 1 - ssh $1 : + _khfix_common "$@" || return 1 + ssh $1 : } khcopy() { - _khfix_common "$@" - ssh-copy-id $1 + _khfix_common "$@" + ssh-copy-id $1 } a() { - beet "${@}" + beet "${@}" } ack() { ack-grep "$@"; } anki() { - if which anki &>/dev/null; then - command anki - else - schroot -c anki -- anki - fi + if which anki &>/dev/null; then + command anki + else + schroot -c anki -- anki + fi } astudio() { - # googling android emulator libGL error: failed to load driver: r600 - # lead to http://stackoverflow.com/a/36625175/14456 - export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 - /a/opt/android-studio/bin/studio.sh "$@" &r; + # googling android emulator libGL error: failed to load driver: r600 + # lead to http://stackoverflow.com/a/36625175/14456 + export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 + /a/opt/android-studio/bin/studio.sh "$@" &r; } b() { - # backwards - c - + # backwards + c - } bkrun() { - # use -p from interactive shell - btrbk-run -p "$@" + # use -p from interactive shell + btrbk-run -p "$@" } bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; } bigclock() { - xclock -digital -update 1 -face 'arial black-80:bold' + xclock -digital -update 1 -face 'arial black-80:bold' } btc() { - local f=/etc/bitcoin/bitcoin.conf - # importprivkey will timeout if using the default of 15 mins. - # upped it to 1 hour. - bitcoin-cli -rpcclienttimeout=60000 -$(s grep rpcuser= $f) -$(s grep rpcpassword= $f) "$@" + local f=/etc/bitcoin/bitcoin.conf + # importprivkey will timeout if using the default of 15 mins. + # upped it to 1 hour. + bitcoin-cli -rpcclienttimeout=60000 -$(s grep rpcuser= $f) -$(s grep rpcpassword= $f) "$@" } btcusd() { # $1 btc in usd - local price - price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" - printf "$%s\n" "$price" - if [[ $1 ]]; then - printf "$%.2f\n" "$(echo "scale=4; $price * $1"| bc -l)" - fi + local price + price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" + printf "$%s\n" "$price" + if [[ $1 ]]; then + printf "$%.2f\n" "$(echo "scale=4; $price * $1"| bc -l)" + fi } usdbtc() { # $1 usd in btc - local price - price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" - printf "$%s\n" "$price" - if [[ $1 ]]; then - # 100 mil satoshi / btc. 8 digits after the 1. - printf "%.8f btc\n" "$(echo "scale=10; $1 / $price "| bc -l)" - fi + local price + price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" + printf "$%s\n" "$price" + if [[ $1 ]]; then + # 100 mil satoshi / btc. 8 digits after the 1. + printf "%.8f btc\n" "$(echo "scale=10; $1 / $price "| bc -l)" + fi } satoshi() { # $1 satoshi in usd - local price - price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" - price=$(echo "scale=10; $price * 0.00000001"| bc -l) - printf "$%f\n" "$price" - if [[ $1 ]]; then - printf "$%.2f\n" "$(echo "scale=10; $price * $1"| bc -l)" - fi + local price + price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" + price=$(echo "scale=10; $price * 0.00000001"| bc -l) + printf "$%f\n" "$price" + if [[ $1 ]]; then + printf "$%.2f\n" "$(echo "scale=10; $price * $1"| bc -l)" + fi } # c. better cd if [[ $RLC_INSIDE_EMACS ]]; then - c() { wcd -c -z 50 -o "$@"; } + c() { wcd -c -z 50 -o "$@"; } else - # lets see what the fancy terminal does from time to time - c() { wcd -c -z 50 "$@"; } + # lets see what the fancy terminal does from time to time + c() { wcd -c -z 50 "$@"; } fi caa() { git commit --amend --no-edit -a; } caf() { - find -L $1 -type f -not \( -name .svn -prune -o -name .git -prune \ - -o -name .hg -prune -o -name .editor-backups -prune \ - -o -name .undo-tree-history -prune \) \ - -exec bash -lc 'hr; echo "$1"; hr; cat "$1"' _ {} \; 2>/dev/null + find -L $1 -type f -not \( -name .svn -prune -o -name .git -prune \ + -o -name .hg -prune -o -name .editor-backups -prune \ + -o -name .undo-tree-history -prune \) \ + -exec bash -lc 'hr; echo "$1"; hr; cat "$1"' _ {} \; 2>/dev/null } calc() { echo "scale=3; $*" | bc -l; } # no having to type quotes, but also no command history: clc() { - local x - read -r x - echo "scale=3; $x" | bc -l + local x + read -r x + echo "scale=3; $x" | bc -l } cam() { - git commit -am "$*" + git commit -am "$*" } ccat () { # config cat. see a config without extra lines. - grep '^\s*[^;[:space:]#]' "$@" + 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" - while IFS= read -r line; do - # the default bright red / blue doesn't work in emacs shell - dwdiff -cblue,red -A best -d " ," <(grep "^$line" "$f1" || echo ) <(grep "^$line" "$f2" || echo ) | colordiff - done < "$unified" + # 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" + while IFS= read -r line; do + # the default bright red / blue doesn't work in emacs shell + dwdiff -cblue,red -A best -d " ," <(grep "^$line" "$f1" || echo ) <(grep "^$line" "$f2" || echo ) | colordiff + done < "$unified" } cgpl() { - if (($#)); then - cp /a/bin/data/COPYING "$@" - else - cp /a/bin/data/COPYING . - fi + if (($#)); then + cp /a/bin/data/COPYING "$@" + else + cp /a/bin/data/COPYING . + fi } capache() { - if (($#)); then - cp /a/bin/data/LICENSE "$@" - else - cp /a/bin/data/LICENSE . - fi + if (($#)); then + cp /a/bin/data/LICENSE "$@" + else + cp /a/bin/data/LICENSE . + fi } chown() { - # makes it so chown -R symlink affects the symlink and its target. - if [[ $1 == -R ]]; then - shift - command chown -h "$@" - command chown -R "$@" - else - command chown "$@" - fi + # makes it so chown -R symlink affects the symlink and its target. + if [[ $1 == -R ]]; then + shift + command chown -h "$@" + command chown -R "$@" + else + command chown "$@" + fi } cim() { - git commit -m "$*" + git commit -m "$*" } cl() { - # choose recent directory. cl = cd list - c = + # choose recent directory. cl = cd list + c = } chrome() { - if type -p chromium &>/dev/null; then - cmd=chromium - else - cd - cmd="schroot -c stretch chromium" - CHROMIUM_FLAGS='--enable-remote-extensions' $cmd &r - fi + if type -p chromium &>/dev/null; then + cmd=chromium + else + cd + cmd="schroot -c stretch chromium" + CHROMIUM_FLAGS='--enable-remote-extensions' $cmd &r + fi } d() { builtin bg; } complete -A stopped -P '"%' -S '"' d dat() { # do all tee, for more complex scripts - tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l) + tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l) } da() { # do all - local host - "$@" - for host in x2 tp treetowl; do - ssh $host "$@" - done + local host + "$@" + for host in x2 tp treetowl; do + ssh $host "$@" + done } dc() { - diff --strip-trailing-cr -w "$@" # diff content + diff --strip-trailing-cr -w "$@" # diff content } 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 + # 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 } despace() { - local x y - for x in "$@"; do - y="${x// /_}" - safe_rename "$x" "$y" - done + local x y + for x in "$@"; do + y="${x// /_}" + safe_rename "$x" "$y" + done } dt() { - date "+%A, %B %d, %r" "$@" + date "+%A, %B %d, %r" "$@" } dus() { # du, sorted, default arg of - du -sh ${@:-*} | sort -h + du -sh ${@:-*} | sort -h } @@ -524,48 +524,48 @@ e() { echo "$@"; } ediff() { - [[ ${#@} == 2 ]] || { echo "error: ediff requires 2 arguments"; return 1; } - emacs --eval "(ediff-files \"$1\" \"$2\")" + [[ ${#@} == 2 ]] || { echo "error: ediff requires 2 arguments"; return 1; } + emacs --eval "(ediff-files \"$1\" \"$2\")" } 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" + 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" } # mail related etail() { - sudo tail -f /var/log/exim4/mainlog + sudo tail -f /var/log/exim4/mainlog } f() { - # cd forward - c + + # cd forward + c + } 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); + # 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); } faf() { # find all files - find -L $1 -not \( -name .svn -prune -o -name .git -prune \ - -o -name .hg -prune -o -name .editor-backups -prune \ - -o -name .undo-tree-history -prune \) 2>/dev/null + find -L $1 -not \( -name .svn -prune -o -name .git -prune \ + -o -name .hg -prune -o -name .editor-backups -prune \ + -o -name .undo-tree-history -prune \) 2>/dev/null } # one that comes with distros is too old for newer devices fastboot() { - /a/opt/android-platform-tools/fastboot "$@"; + /a/opt/android-platform-tools/fastboot "$@"; } kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; } @@ -591,181 +591,199 @@ kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; } # usually good enough to just rm -rf /data/app/APPNAME # # currently broken: +# # causes replicant to crash +# org.quantumbadger.redreader +# org.kde.kdeconnect_tp + +# not broke, but won't work without gps +#com.zoffcc.applications.zanavi +# not broke, but not using atm +#com.nutomic.syncthingandroid +#org.fedorahosted.freeotp +# # doesn\'t work on replicant +#net.sourceforge.opencamera +# fdroid_pkgs=( - at.bitfire.davdroid - com.alaskalinuxuser.justnotes - com.artifex.mupdfdemo - com.fsck.k9 - com.ichi2.anki - com.jmstudios.redmoon - com.notecryptpro - com.nutomic.syncthingandroid - com.termux - com.zoffcc.applications.zanavi - cz.martykan.forecastie - de.danoeh.antennapod - im.vector.alpha # riot - info.papdt.blackblub - me.tripsit.tripmobile - net.gaast.giggity - net.osmand.plus - net.sourceforge.opencamera - org.dmfs.tasks # caldav tasks thing - org.fdroid.fdroid - org.isoron.uhabits - org.kde.kdeconnect_tp - org.quantumbadger.redreader - org.smssecure.smssecure - org.fedorahosted.freeotp - org.yaaic + at.bitfire.davdroid + com.alaskalinuxuser.justnotes + com.artifex.mupdf.viewer.app + com.fsck.k9 + com.ghostsq.commander + com.ichi2.anki + com.jmstudios.redmoon + com.jmstudios.chibe + com.notecryptpro + com.termux + cz.martykan.forecastie + de.danoeh.antennapod + im.vector.alpha # riot + info.papdt.blackblub + me.tripsit.tripmobile + net.gaast.giggity + net.osmand.plus + org.isoron.uhabits + org.smssecure.smssecure + org.yaaic ) # https://forum.xda-developers.com/android/software-hacking/wip-selinux-capable-superuser-t3216394 # for maru, #me.phh.superuser fdup() { - local -A installed updated - local p + local -A installed updated + local p + fdroidcl update + if fdroidcl search -u | grep ^org.fdroid.fdroid; then + fdroidcl upgrade org.fdroid.fdroid + sleep 5 fdroidcl update - for p in $(fdroidcl search -i| grep -o "^\S\+"); do - installed[$p]=true - done - for p in $(fdroidcl search -u| grep -o "^\S\+"); do - updated[$p]=false - done - for p in ${fdroid_pkgs[@]}; do - ${installed[$p]:-false} || fdroidcl install $p - done - for p in ${!installed[@]}; do - ${updated[$p]:-true} || fdroidcl upgrade $p - done + fi + for p in $(fdroidcl search -i| grep -o "^\S\+"); do + installed[$p]=true + done + for p in $(fdroidcl search -u| grep -o "^\S\+"); do + updated[$p]=false + done + for p in ${fdroid_pkgs[@]}; do + if ! ${installed[$p]:-false}; then + fdroidcl install $p + # sleeps are just me being paranoid since replicant has a history of crashing when certain apps are installed + sleep 5 + fi + done + for p in ${!installed[@]}; do + if ! ${updated[$p]:-true}; then + fdroidcl upgrade $p + sleep 5 + fi + done } firefox-default-profile() { - key=Default value=1 section=$1 - file=/p/c/subdir_files/.mozilla/firefox/profiles.ini - sed -ri "/^ *$key/d" "$file" - sed -ri "/ *\[$section\]/,/^ *\[[^]]+\]/{/^\s*$key[[:space:]=]/d};/ *\[$section\]/a $key=$value" "$file" + key=Default value=1 section=$1 + file=/p/c/subdir_files/.mozilla/firefox/profiles.ini + sed -ri "/^ *$key/d" "$file" + sed -ri "/ *\[$section\]/,/^ *\[[^]]+\]/{/^\s*$key[[:space:]=]/d};/ *\[$section\]/a $key=$value" "$file" } fdhome() { #firefox default home profile - firefox-default-profile Profile0 + firefox-default-profile Profile0 } fdwork() { - firefox-default-profile Profile4 + firefox-default-profile Profile4 } ff() { - if type -P firefox &>/dev/null; then - firefox "$@" - else - iceweasel "$@" - fi + if type -P firefox &>/dev/null; then + firefox "$@" + else + iceweasel "$@" + fi } fn() { - firefox -P alt "$@" >/dev/null 2>&1 + firefox -P alt "$@" >/dev/null 2>&1 } fsdiff () { - local missing=false - local dname="${PWD##*/}" - local m="/a/tmp/$dname-missing" - local d="/a/tmp/$dname-diff" - [[ -e $d ]] && rm "$d" - [[ -e $m ]] && rm "$m" - local msize=0 - local fsfile - while read -r line; do - fsfile="$1${line#.}" - if [[ -e "$fsfile" ]]; then - md5diff "$line" "$fsfile" && tee -a "/a/tmp/$dname-diff" <<< "$fsfile $line" - else - missing=true - echo "$line" >> "$m" - msize=$((msize + 1)) - fi - done < <(find -type f ) - if $missing; then - echo "$m" - (( msize <= 100 )) && cat $m + local missing=false + local dname="${PWD##*/}" + local m="/a/tmp/$dname-missing" + local d="/a/tmp/$dname-diff" + [[ -e $d ]] && rm "$d" + [[ -e $m ]] && rm "$m" + local msize=0 + local fsfile + while read -r line; do + fsfile="$1${line#.}" + if [[ -e "$fsfile" ]]; then + md5diff "$line" "$fsfile" && tee -a "/a/tmp/$dname-diff" <<< "$fsfile $line" + else + missing=true + echo "$line" >> "$m" + msize=$((msize + 1)) fi + done < <(find -type f ) + if $missing; then + echo "$m" + (( 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 - mkdir c - echo ok > c/d - local x=$(mktemp -d) - mkdir $x/c - echo different > $x/c/d - 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 + cd $(mktemp -d) + echo ok > a + echo nok > b + mkdir c + echo ok > c/d + local x=$(mktemp -d) + mkdir $x/c + echo different > $x/c/d + echo ok > $x/a + fsdiff $x } 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 - { sums+=( "$(md5sum < "$x")" ) ; } 2>/dev/null + # 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 + { sums+=( "$(md5sum < "$x")" ) ; } 2>/dev/null + done + while read -r line; do + { missing_sum=$(md5sum < "$line") ; } 2>/dev/null + renamed=false + for x in "${sums[@]}"; do + if [[ $missing_sum == "$x" ]]; then + renamed=true + break + fi done - while read -r line; do - { missing_sum=$(md5sum < "$line") ; } 2>/dev/null - renamed=false - for x in "${sums[@]}"; do - if [[ $missing_sum == "$x" ]]; then - renamed=true - break - fi - done - $renamed || echo "$line" - done < "$1" - return 0 + $renamed || echo "$line" + done < "$1" + return 0 } feh() { - # F = fullscren, z = random, Z = auto zoom - command feh -FzZ "$@" + # F = fullscren, z = random, Z = auto zoom + command feh -FzZ "$@" } # mail related frozen() { - rm -rf /tmp/frozen - s mailq |gr frozen|awk '{print $3}' | while read -r id; do - s exim -Mvl $id - echo - s exim -Mvh $id - echo - s exim -Mvb $id - echo -e '\n\n##############################\n' - done | tee -a /tmp/frozen + rm -rf /tmp/frozen + s mailq |gr frozen|awk '{print $3}' | while read -r id; do + s exim -Mvl $id + echo + s exim -Mvh $id + echo + s exim -Mvb $id + echo -e '\n\n##############################\n' + done | tee -a /tmp/frozen } frozenrm() { - local ids=() - while read -r line; do - printf '%s\n' "$line" - ids+=($(printf '%s\n' "$line" |gr frozen|awk '{print $3}')) - done < <(s mailq) - echo "sleeping for 2 in case you change your mind" - sleep 2 - s exim -Mrm "${ids[@]}" + local ids=() + while read -r line; do + printf '%s\n' "$line" + ids+=($(printf '%s\n' "$line" |gr frozen|awk '{print $3}')) + done < <(s mailq) + echo "sleeping for 2 in case you change your mind" + sleep 2 + s exim -Mrm "${ids[@]}" } 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\" } + # 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 @@ -773,221 +791,230 @@ return' ERR fw() { - firefox -P default "$@" >/dev/null 2>&1 + firefox -P default "$@" >/dev/null 2>&1 } getdir () { - local help="Usage: getdir [--help] PATH + local help="Usage: getdir [--help] PATH Output the directory of PATH, or just PATH if it is a directory." - if [[ $1 == --help ]]; then - echo "$help" - return 0 - fi - if [[ $# -ne 1 ]]; then - echo "getdir error: expected 1 argument, got $#" - return 1 - fi - if [[ -d $1 ]]; then - echo "$1" + if [[ $1 == --help ]]; then + echo "$help" + return 0 + fi + if [[ $# -ne 1 ]]; then + echo "getdir error: expected 1 argument, got $#" + return 1 + fi + if [[ -d $1 ]]; then + echo "$1" + else + local dir="$(dirname "$1")" + if [[ -d $dir ]]; then + echo "$dir" else - local dir="$(dirname "$1")" - if [[ -d $dir ]]; then - echo "$dir" - else - echo "getdir error: directory does not exist" - return 1 - fi + echo "getdir error: directory does not exist" + return 1 fi + fi } 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 + [[ $# == 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 } gitroot() { - local help="Usage: gitroot [--help] + local help="Usage: gitroot [--help] Print the full path to the root of the current git repo Handles being within a .git directory, unlike git rev-parse --show-toplevel, and works in older versions of git which did not have that." - if [[ $1 == --help ]]; then - echo "$help" - return - fi - local p=$(git rev-parse --git-dir) || { echo "error: not in a git repo" ; return 1; } - [[ $p != /* ]] && p=$PWD - echo "${p%%/.git}" + if [[ $1 == --help ]]; then + echo "$help" + return + fi + local p=$(git rev-parse --git-dir) || { echo "error: not in a git repo" ; return 1; } + [[ $p != /* ]] && p=$PWD + echo "${p%%/.git}" } gitian() { - git config user.email ian@iankelling.org + git config user.email ian@iankelling.org +} + +gh() { + # i got an error, gh not found when doing a pull request, it seems like it wants itself in it's path. + local _oldpath="$PATH" + PATH="$PATH:~/node_modules/.bin" + command gh "$@" + PATH="$_oldpath" } gmacs() { - # quit will prompt if the program crashes. - gdb -ex=r -ex=quit --args emacs "$@"; r; + # quit will prompt if the program crashes. + gdb -ex=r -ex=quit --args emacs "$@"; r; } gdkill() { - # kill the emacs daemon - pk1 emacs --daemon + # kill the emacs daemon + pk1 emacs --daemon } gse() { - git send-email --notes '--envelope-sender=' \ - --suppress-cc=self "$@" + git send-email --notes '--envelope-sender=' \ + --suppress-cc=self "$@" } gr() { - grep -iIP --color=auto "$@" + grep -iIP --color=auto "$@" } grr() { - if [[ ${#@} == 1 ]]; then - grep -riIP --color=auto "$@" . - else - grep -riIP --color=auto "$@" - fi + if [[ ${#@} == 1 ]]; then + grep -riIP --color=auto "$@" . + else + grep -riIP --color=auto "$@" + fi } hstatus() { - # do git status on published repos + # do git status on published repos + cd /a/bin/githtml + for x in !(forks) forks/* ian-specific/*; do + cd `readlink -f $x`/.. + hr + echo $x + i status cd /a/bin/githtml - for x in !(forks) forks/* ian-specific/*; do - cd `readlink -f $x`/.. - hr - echo $x - i status - cd /a/bin/githtml - done + done } 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 + # 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:-60}) - echo + printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq ${COLUMNS:-60}) + echo } hrcat() { local f; for f; do [[ -f $f ]] || continue; hr; echo "$f"; cat "$f"; done } +hub() { /nocow/t/hub-linux-amd64-2.3.0-pre10/bin/hub "$@"; } 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 + || complete -o default -o nospace -F _git i if ! type service &>/dev/null; then - service() { - echo actually running: systemctl $2 $1 - systemctl $2 $1 - } + service() { + echo actually running: systemctl $2 $1 + systemctl $2 $1 + } fi ic() { - # fast commit all - git commit -am "$*" + # fast commit all + git commit -am "$*" } idea() { - /a/opt/idea-IC-163.7743.44/bin/idea.sh "$@" &r + /a/opt/idea-IC-163.7743.44/bin/idea.sh "$@" &r } ifn() { - # insensitive find - find -L . -not \( -name .svn -prune -o -name .git -prune \ - -o -name .hg -prune -o -name .editor-backups -prune \ - -o -name .undo-tree-history -prune \) -iname "*$**" 2>/dev/null + # insensitive find + find -L . -not \( -name .svn -prune -o -name .git -prune \ + -o -name .hg -prune -o -name .editor-backups -prune \ + -o -name .undo-tree-history -prune \) -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* & - } + # 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 - } + o() { + if type gvfs-open &> /dev/null ; then + gvfs-open "$@" + else + xdg-open "$@" + fi + # another alternative is run-mailcap + } fi ipdrop() { - s iptables -A INPUT -s $1 -j DROP + s iptables -A INPUT -s $1 -j DROP } net-dev-info() { - e "lspci -nnk|gr -iA2 net" - lspci -nnk|gr -iA2 net - hr - e "s lshw -C network" - hr - s lshw -C network + e "lspci -nnk|gr -iA2 net" + lspci -nnk|gr -iA2 net + hr + e "s lshw -C network" + hr + s lshw -C network } istext() { - grep -Il "" "$@" &>/dev/null + grep -Il "" "$@" &>/dev/null } jtail() { - journalctl -n 10000 -f "$@" | grep -Evi "^(\S+\s+){4}(sudo|sshd|cron)" + journalctl -n 10000 -f "$@" | grep -Evi "^(\S+\s+){4}(sudo|sshd|cron)" } kff() { # keyboardio firmware flash - pushd /a/bin/distro-setup/Arduino/Model01-Firmware - yes $'\n' | make flash - popd + pushd /a/bin/distro-setup/Arduino/Model01-Firmware + yes $'\n' | make flash + popd } l() { - if [[ $PWD == /[iap] ]]; then - command ls -A --color=auto -I lost+found "$@" - else - command ls -A --color=auto "$@" - fi + if [[ $PWD == /[iap] ]]; then + command ls -A --color=auto -I lost+found "$@" + else + command ls -A --color=auto "$@" + fi } @@ -996,80 +1023,80 @@ lcn() { locate -i "*$**"; } lld() { ll -d "$@"; } low() { # make filenames lowercase, remove bad chars - local f new - for f in "$@"; do - new="${f,,}" # downcase - new="${new//[^[:alnum:]._-]/_}" # sub bad chars - new="${new#"${new%%[[:alnum:]]*}"}" # remove leading/trailing non-alnum - new="${new%"${new##*[[:alnum:]]}"}" - # remove bad underscores, like __ and _._ - new=$(echo $new | sed -r 's/__+/_/g;s/_+([.-])|([.-])_+/\1/g') - safe_rename "$f" "$new" || return 1 - done - return 0 + local f new + for f in "$@"; do + new="${f,,}" # downcase + new="${new//[^[:alnum:]._-]/_}" # sub bad chars + new="${new#"${new%%[[:alnum:]]*}"}" # remove leading/trailing non-alnum + new="${new%"${new##*[[:alnum:]]}"}" + # remove bad underscores, like __ and _._ + new=$(echo $new | sed -r 's/__+/_/g;s/_+([.-])|([.-])_+/\1/g') + safe_rename "$f" "$new" || return 1 + done + return 0 } 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" || return 1 - fi - done + 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" || return 1 + fi + done } k() { # history search - grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 80; + grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 80; } ks() { # history search - grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | uniq; + grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | uniq; } 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]}' + # 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]}' } mbenable() { - mb=$1 - dst=/m/4e/$1 - src=/m/md/$1 - set -x - mv -T $src $dst || { set +x; return 1; } - ln -s -T $dst $src - /a/exe/lnf /p/.mu ~ - mu index --maildir=/m/4e - set +x + mb=$1 + dst=/m/4e/$1 + src=/m/md/$1 + set -x + mv -T $src $dst || { set +x; return 1; } + ln -s -T $dst $src + /a/exe/lnf /p/.mu ~ + mu index --maildir=/m/4e + set +x } mbdisable() { - mb=$1 - dst=/m/md/$1 - src=/m/4e/$1 - set -x - if [[ -L $dst ]]; then rm $dst; fi - mv -T $src $dst - set +x + mb=$1 + dst=/m/md/$1 + src=/m/4e/$1 + set -x + if [[ -L $dst ]]; then rm $dst; fi + mv -T $src $dst + set +x } mdt() { - markdown -o /tmp/mdtest.html "$1" - firefox /tmp/mdtest.html + markdown "$1" >/tmp/mdtest.html + firefox /tmp/mdtest.html } mkc() { - mkdir "$1" - c "$1" + mkdir "$1" + c "$1" } mkt() { # mkdir and touch file - local path="$1" - mkdir -p "$(dirname "$path")" - touch "$path" + local path="$1" + mkdir -p "$(dirname "$path")" + touch "$path" } mkdir() { command mkdir -p "$@"; } @@ -1077,257 +1104,251 @@ mkdir() { command mkdir -p "$@"; } mo() { xset dpms force off; } # monitor off otp() { - oathtool --totp -b "$@" | xclip -selection clipboard + oathtool --totp -b "$@" | xclip -selection clipboard } -# pithosfly is broken due to bitrot. -pithos() { - cd / - export PYTHONPATH=/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 + # 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*" + [[ $# != 1 ]] && { echo requires 1 argument; return 1; } + local pathArray + IFS=: pathArray=($PATH); unset IFS + find "${pathArray[@]}" -iname "*$1*" } pk1() { - local pid - pid=($(pgrep -f "$*")) - case ${#pid[@]} in - 1) - ps -F $pid - m kill $pid - ;; - 0) echo "no pid found" ;; - *) - ps -F ${pid[@]} - ;; - esac + local pid + pid=($(pgrep -f "$*")) + case ${#pid[@]} in + 1) + ps -F $pid + m kill $pid + ;; + 0) echo "no pid found" ;; + *) + ps -F ${pid[@]} + ;; + esac } 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 + # 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 } ping8() { ping 8.8.8.8; } pub() { - rld /a/h/_site/ li:/var/www/iankelling.org/html + rld /a/h/_site/ li:/var/www/iankelling.org/html } pubip() { curl -4s https://icanhazip.com; } whatismyip() { pubip; } pumpa() { - # fixes the menu bar in xmonad. this won\'t be needed when xmonad - # packages catches up on some changes in future (this is written in - # 4/2017) - # - # geekosaur: so you'll want to upgrade to xmonad 0.13 or else use a - # locally modified XMonad.Hooks.ManageDocks that doesn't set the - # work area; turns out it's impossible to set correctly if you are - # not a fully EWMH compliant desktop environment - # - # geekosaur: chrome shows one failure mode, qt/kde another, other - # gtk apps a third, ... I came up with a setting that works for me - # locally but apparently doesn't work for others, so we joined the - # other tiling window managers in giving up on setting it at all - # - xprop -root -remove _NET_WORKAREA - command pumpa &r + # fixes the menu bar in xmonad. this won\'t be needed when xmonad + # packages catches up on some changes in future (this is written in + # 4/2017) + # + # geekosaur: so you'll want to upgrade to xmonad 0.13 or else use a + # locally modified XMonad.Hooks.ManageDocks that doesn't set the + # work area; turns out it's impossible to set correctly if you are + # not a fully EWMH compliant desktop environment + # + # geekosaur: chrome shows one failure mode, qt/kde another, other + # gtk apps a third, ... I came up with a setting that works for me + # locally but apparently doesn't work for others, so we joined the + # other tiling window managers in giving up on setting it at all + # + xprop -root -remove _NET_WORKAREA + command pumpa &r } pwgen() { - # -m = min length - # -x = max length - # -t = print pronunciation - apg -m 12 -x 16 -t + # -m = min length + # -x = max length + # -t = print pronunciation + apg -m 14 -x 17 -t } pwlong() { - # -M CLN = use Caps, Lowercase, Numbers - # -n 1 = 1 password - # -a 1 = use random instead of pronounceable algorithm - apg -m 50 -x 70 -n 1 -a 1 -M CLN + # -M CLN = use Caps, Lowercase, Numbers + # -n 1 = 1 password + # -a 1 = use random instead of pronounceable algorithm + apg -m 50 -x 70 -n 1 -a 1 -M CLN } q() { # start / launch a program in the backround and redir output to null - "$@" &> /dev/null & + "$@" &> /dev/null & } r() { - exit "$@" 2>/dev/null + 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 "$@" + # 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 "$@" + # 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 "$@" + # rl without preserving modification time. + rsync -ahvic --delete --no-t "$@" } rlu() { # [OPTS] HOST PATH - # eg. rlu -opts frodo /testpath - # relative paths will expanded with readlink -f. - # 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 - path=$(readlink -f $path) - 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:/"; + # eg. rlu -opts frodo /testpath + # relative paths will expanded with readlink -f. + # 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 + path=$(readlink -f $path) + 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:/"; } # only run on desktop. simpler to keep this on one system. r2eadd() { # usage: name url - # initial setup of rss2email: - # r2e new r2e@iankelling.org - # that initializes files, and sets default email. - # symlink to the config doesn't work, so I copied it to /p/c - # and then use cli option to specify explicit path. - # Only option changed from default config is to set - # force-from = True - # - # or else for a few feeds, the from address is set by the feed, and - # if I fail delivery, then I send a bounce message to that from - # address, which makes me be a spammer. - - r2e add $1 "$2" $1@r2e.iankelling.org - # get up to date and don't send old entries now: - r2e run --no-send $1 + # initial setup of rss2email: + # r2e new r2e@iankelling.org + # that initializes files, and sets default email. + # symlink to the config doesn't work, so I copied it to /p/c + # and then use cli option to specify explicit path. + # Only option changed from default config is to set + # force-from = True + # + # or else for a few feeds, the from address is set by the feed, and + # if I fail delivery, then I send a bounce message to that from + # address, which makes me be a spammer. + + r2e add $1 "$2" $1@r2e.iankelling.org + # get up to date and don't send old entries now: + r2e run --no-send $1 } r2e() { command r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg "$@"; } rspicy() { # usage: HOST DOMAIN - # connect to spice vm remote host. use vspicy for local host - local port=$(ssh $1<2 - return 1 - fi - if [[ $1 != $2 ]]; then # yes, we want to silently ignore this - if [[ -e $2 || -L $2 ]]; then - echo "Cannot rename $1 to $2 as it already exists." - else - mv -vi "$1" "$2" - fi + # mv -n exists, but it's silent + if [[ $# != 2 ]]; then + echo safe_rename error: $# args, need 2 >2 + return 1 + fi + if [[ $1 != $2 ]]; then # yes, we want to silently ignore this + if [[ -e $2 || -L $2 ]]; then + echo "Cannot rename $1 to $2 as it already exists." + else + mv -vi "$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 "$@" + # 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 scssl() { - # s gem install scss-lint - pushd /a/opt/thoughtbot-guides - git pull --stat - popd - scss-lint -c /a/opt/thoughtbot-guides/style/sass/.scss-lint.yml "$@" + # s gem install scss-lint + pushd /a/opt/thoughtbot-guides + git pull --stat + popd + scss-lint -c /a/opt/thoughtbot-guides/style/sass/.scss-lint.yml "$@" } ser() { - local s; [[ $EUID != 0 ]] && s=sudo - if type -p systemctl &>/dev/null; then - $s systemctl $1 $2 - else - $s service $2 $1 - fi + local s; [[ $EUID != 0 ]] && s=sudo + if type -p systemctl &>/dev/null; then + $s systemctl $1 $2 + else + $s service $2 $1 + fi } setini() { # set a value in a .ini style file - key="$1" value="$2" section="$3" file="$4" - if [[ -s $file ]]; then - sed -ri -f - "$file" <"$file" <"$file" </dev/null; then - ser enable $service - fi + service=$1 + ser restart $service || return 1 + 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 "$@" + # 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 "$@" } skaraoke() { - local tmp out - in="$1" - out=${2:-${1%.*}.sh} - tmp=$(mktemp -d) - script -t -c "mpv --no-config --no-resume-playback --no-terminal --no-audio-display '$1'" $tmp/typescript 2>$tmp/timing - # todo, the current sleep seems pretty good, but it - # would be nice to have an empirical measurement, or - # some better wait to sync up. - # - # note: --loop-file=no prevents it from hanging if you have that - # set to inf the mpv config. - # --loop=no prevents it from exit code 3 due to stdin if you - # had it set to inf in mpv config. - # - # args go to mpv, for example --volume=80, 50% - cat >$out <$tmp/timing + # todo, the current sleep seems pretty good, but it + # would be nice to have an empirical measurement, or + # some better wait to sync up. + # + # note: --loop-file=no prevents it from hanging if you have that + # set to inf the mpv config. + # --loop=no prevents it from exit code 3 due to stdin if you + # had it set to inf in mpv config. + # + # args go to mpv, for example --volume=80, 50% + cat >$out <= 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 + # 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" + #logRoot="$HOME/typescripts/" + #scriptreplay "$logRoot$1.t" "$logRoot$1.s" + scriptreplay "$1.t" "$1.s" } spend() { - s systemctl suspend + s systemctl suspend } 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 + # 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 "$@" + # with -ll, less secure but faster. + command srm -ll "$@" } srun() { - scp $2 $1:/tmp - ssh $1 /tmp/${2##*/} "${@:2}" + scp $2 $1:/tmp + ssh $1 /tmp/${2##*/} "${@:2}" } sss() { # ssh solo - ssh -oControlMaster=no -oControlPath=/ "$@" + ssh -oControlMaster=no -oControlPath=/ "$@" } ssk() { - local -a opts=() - while [[ $1 == -* ]]; do - opts+=("$1") - shift - done - m pkill -f "^ssh: /tmp/ssh_mux_${USER}_${1#*@}_22_" - m ssh "${opts[@]}" "$@" + local -a opts=() + while [[ $1 == -* ]]; do + opts+=("$1") + shift + done + m pkill -f "^ssh: /tmp/ssh_mux_${USER}_${1#*@}_22_" + m ssh "${opts[@]}" "$@" } swap() { - local tmp - tmp=$(mktemp) - mv $1 $tmp - mv $2 $1 - mv $tmp $2 + local tmp + tmp=$(mktemp) + mv $1 $tmp + mv $2 $1 + mv $tmp $2 } t() { - local x - local -a args - if type -t trash-put >/dev/null; then - # skip args that don't exist, or else trash-put will have an error - for x in "$@"; do - if [[ -e $x || -L $x ]]; then - args+=("$x") - fi - 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/tmp/testsieve.log 2> >(tail) && sed -rn '/^Performed actions:/{n;n;p}' /tmp/testsieve.log | sort -u - } - - - # mail related - # plain sieve - testsieve() { - sieve-filter ~/sieve/main.sieve "$@" - } - - # mail related - testexim() { - # testmail above calls sendmail, which is a link to exim/postfix. - # it's docs don't say a way of adding an argument - # to sendmail to turn on debug output. We could make a wrapper, but - # that is a pain. Exim debug args are documented here: - # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html - # - # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-building_and_installing_exim.html - # note, for exim daemon, you can turn on debug options by - # adding -d, etc to COMMONOPTIONS in - # /etc/default/exim4 - # for testing external mail, you need the to address as final cmdline arg - exim -d+tls -t <<'EOF' + local x + local -a args + if type -t trash-put >/dev/null; then + # skip args that don't exist, or else trash-put will have an error + for x in "$@"; do + if [[ -e $x || -L $x ]]; then + args+=("$x") + fi + 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/tmp/testsieve.log 2> >(tail) && sed -rn '/^Performed actions:/{n;n;p}' /tmp/testsieve.log | sort -u +} + + +# mail related +# plain sieve +testsieve() { + sieve-filter ~/sieve/main.sieve "$@" +} + +# mail related +testexim() { + # testmail above calls sendmail, which is a link to exim/postfix. + # it's docs don't say a way of adding an argument + # to sendmail to turn on debug output. We could make a wrapper, but + # that is a pain. Exim debug args are documented here: + # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html + # + # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-building_and_installing_exim.html + # note, for exim daemon, you can turn on debug options by + # adding -d, etc to COMMONOPTIONS in + # /etc/default/exim4 + # for testing external mail, you need the to address as final cmdline arg + exim -d+tls -t <<'EOF' From: root@frodo.lan To: ian@mail.iankelling.org Subject: Testing Exim This is a test message. EOF - } - - tm() { - # timer in minutes - # --no-config - (sleep $(calc "$@ * 60") && mpv --no-config --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 & - } - - trg() { transmission-remote-gtk&r; } - trc() { - # example, set global upload limit to 100 kilobytes: - # trc -u 100 - TR_AUTH=":$(jq -r .profiles[0].password ~/.config/transmission-remote-gtk/config.json)" transmission-remote transmission.lan -ne "$@" - } - - - 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 +} + +tm() { + # timer in minutes + # --no-config + (sleep $(calc "$@ * 60") && mpv --no-config --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 & +} + +tpx2() { + case $HOSTNAME in + tp) target=x2 ;; + x2) target=tp ;; + esac + btrbk-run -t $target -pv && switch-mail-host $HOSTNAME $target +} + +trg() { transmission-remote-gtk&r; } +trc() { + # example, set global upload limit to 100 kilobytes: + # trc -u 100 + TR_AUTH=":$(jq -r .profiles[0].password ~/.config/transmission-remote-gtk/config.json)" transmission-remote transmission.lan -ne "$@" +} + + +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 } psnetns() { - # show all processes in the network namespace $1. - # blank entries appear to be subprocesses/threads - local x netns - netns=$1 - ps -w | head -n 1 - s find -L /proc/[1-9]*/task/*/ns/net -samefile /run/netns/$netns | cut -d/ -f5 | \ - while read l; do - x=$(ps -w --no-headers -p $l); - if [[ $x ]]; then echo "$x"; else echo $l; fi; - done + # show all processes in the network namespace $1. + # blank entries appear to be subprocesses/threads + local x netns + netns=$1 + ps -w | head -n 1 + s find -L /proc/[1-9]*/task/*/ns/net -samefile /run/netns/$netns | cut -d/ -f5 | \ + while read l; do + x=$(ps -w --no-headers -p $l); + if [[ $x ]]; then echo "$x"; else echo $l; fi; + done } m() { printf "%s\n" "$*"; "$@"; } vpncmd() { - m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf") -n -m "$@" + m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf") -n -m "$@" } vpnf() { - vpncmd gksudo -u iank "firefox -no-remote -P firefox-main-profile" &r + vpncmd gksudo -u iank "firefox -no-remote -P firefox-main-profile" &r } vpnbash() { - vpncmd bash + vpncmd bash } virshrm() { - for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done + 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/(/dev/null - fi - mate-screensaver-command --exit &>/dev/null - if ! pidof xscreensaver; then - pushd / - xscreensaver & - popd - # 1 was not long enough - sleep 3 - fi - xscreensaver-command -activate + fi + mate-screensaver-command --exit &>/dev/null + if ! pidof xscreensaver; then + pushd / + xscreensaver & + popd + # 1 was not long enough + sleep 3 + fi + xscreensaver-command -activate } ############################# @@ -1739,26 +1768,26 @@ xl() { # from curl cheat.sh/:bash_completion _cheatsh_complete_curl() { - local cur prev opts - _get_comp_words_by_ref -n : cur - - COMPREPLY=() - #cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="$(curl -s cheat.sh/:list | sed s@^@cheat.sh/@)" - - if [[ ${cur} == cheat.sh/* ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - __ltrim_colon_completions "$cur" - return 0 - fi + local cur prev opts + _get_comp_words_by_ref -n : cur + + COMPREPLY=() + #cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + opts="$(curl -s cheat.sh/:list | sed s@^@cheat.sh/@)" + + if [[ ${cur} == cheat.sh/* ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + __ltrim_colon_completions "$cur" + return 0 + fi } complete -F _cheatsh_complete_curl curl if [[ $- == *i* ]]; then - # commands to run when bash exits normally - trap "hl" EXIT + # commands to run when bash exits normally + trap "hl" EXIT fi @@ -1773,52 +1802,52 @@ match_lhs="" [[ -f ~/.dir_colors ]] && match_lhs="${match_lhs}$(<~/.dir_colors)" [[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(/dev/null \ - && match_lhs=$(dircolors --print-database) + && 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 - } + 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 -else + 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 +else + get_term_color() { + : + } fi # Try to keep environment pollution down, EPA loves us. unset safe_term match_lhs use_color @@ -1834,112 +1863,112 @@ unset safe_term match_lhs use_color if [[ $- == *i* ]]; then - # git branch/status prompt function - if [[ $OS != Windows_NT ]]; then - GIT_PS1_SHOWDIRTYSTATE=true - fi - # arch source lopip show -fcation - [[ -r /usr/share/git/git-prompt.sh ]] && source /usr/share/git/git-prompt.sh - # fedora/debian source - [[ -r /usr/share/git-core/contrib/completion/git-prompt.sh ]] && source /usr/share/git-core/contrib/completion/git-prompt.sh - - # in case we didn't source git-prompt.sh - if ! declare -f __git_ps1 > /dev/null; then - __git_ps1() { - : - } - fi - - # this needs to come before next ps1 stuff - # this stuff needs bash 4, feb 2009, - # old enough to no longer condition on $BASH_VERSION anymore - shopt -s autocd - shopt -s dirspell - PS1='\w' - if [[ $- == *i* ]] && [[ ! $RLC_INSIDE_EMACS ]]; then - PROMPT_DIRTRIM=2 - bind -m vi-command B:shell-backward-word - bind -m vi-command W:shell-forward-word - fi - - if [[ $SSH_CLIENT ]]; then - PS1="\h $PS1" - fi + # git branch/status prompt function + if [[ $OS != Windows_NT ]]; then + GIT_PS1_SHOWDIRTYSTATE=true + fi + # arch source lopip show -fcation + [[ -r /usr/share/git/git-prompt.sh ]] && source /usr/share/git/git-prompt.sh + # fedora/debian source + [[ -r /usr/share/git-core/contrib/completion/git-prompt.sh ]] && source /usr/share/git-core/contrib/completion/git-prompt.sh + + # in case we didn't source git-prompt.sh + if ! declare -f __git_ps1 > /dev/null; then + __git_ps1() { + : + } + fi + # this needs to come before next ps1 stuff + # this stuff needs bash 4, feb 2009, + # old enough to no longer condition on $BASH_VERSION anymore + shopt -s autocd + shopt -s dirspell + PS1='\w' + if [[ $- == *i* ]] && [[ ! $RLC_INSIDE_EMACS ]]; then + PROMPT_DIRTRIM=2 + bind -m vi-command B:shell-backward-word + bind -m vi-command W:shell-forward-word + fi + if [[ $SSH_CLIENT ]]; then + PS1="\h $PS1" + fi - prompt-command() { - local return=$? # this MUST COME FIRST - local psc pst ps_char ps_color stale_subvol - unset IFS - history -a # save history + prompt-command() { + local return=$? # this MUST COME FIRST + local psc pst ps_char ps_color stale_subvol + unset IFS + history -a # save history - case $return in - 0) ps_color="$(get_term_color blue)" - ps_char='\$' - ;; - 1) ps_color="$(get_term_color green)" - ps_char="$return \\$" - ;; - *) ps_color="$(get_term_color yellow)" - ps_char="$return \\$" - ;; - esac - if [[ ! -O . ]]; then # not owner - if [[ -w . ]]; then # writable - ps_color="$(get_term_color bold red)" - else - ps_color="$(get_term_color bold green)" - fi - fi - # I would set nullglob, but bash has had bugs where that - # doesn't work if not in top level. - if [[ -e /nocow/btrfs-stale ]] && ((`ls -AUq /nocow/btrfs-stale|wc -l`)); then - ps_char="! $ps_char" - fi - PS1="${PS1%"${PS1#*[wW]}"} \[$ps_color\]$ps_char\[$(get_term_color nocolor)\] " - # emacs completion doesn't like the git prompt atm, so disabling it. - #PS1="${PS1%"${PS1#*[wW]}"}$(__git_ps1 ' (%s)') \[$ps_color\]$ps_char\[$(get_term_color nocolor)\] " - } - PROMPT_COMMAND=prompt-command - settitle () { - if [[ $TERM == screen* ]]; then - local title_escape="\033]..2;" - else - local title_escape="\033]0;" - fi - if [[ $* != prompt-command ]]; then - echo -ne "$title_escape$USER@$HOSTNAME ${PWD/#$HOME/~} $*\007" - fi - } - # for titlebar - # condition from the screen man page i think - if [[ $TERM == *(screen*|xterm*|rxvt*) ]]; then - trap 'settitle "$BASH_COMMAND"' DEBUG + case $return in + 0) ps_color="$(get_term_color blue)" + ps_char='\$' + ;; + 1) ps_color="$(get_term_color green)" + ps_char="$return \\$" + ;; + *) ps_color="$(get_term_color yellow)" + ps_char="$return \\$" + ;; + esac + if [[ ! -O . ]]; then # not owner + if [[ -w . ]]; then # writable + ps_color="$(get_term_color bold red)" + else + ps_color="$(get_term_color bold green)" + fi + fi + # I would set nullglob, but bash has had bugs where that + # doesn't work if not in top level. + if [[ -e /nocow/btrfs-stale ]] && ((`ls -AUq /nocow/btrfs-stale|wc -l`)); then + ps_char="! $ps_char" + fi + PS1="${PS1%"${PS1#*[wW]}"} \[$ps_color\]$ps_char\[$(get_term_color nocolor)\] " + # emacs completion doesn't like the git prompt atm, so disabling it. + #PS1="${PS1%"${PS1#*[wW]}"}$(__git_ps1 ' (%s)') \[$ps_color\]$ps_char\[$(get_term_color nocolor)\] " + } + PROMPT_COMMAND=prompt-command + + settitle () { + if [[ $TERM == screen* ]]; then + local title_escape="\033]..2;" else - trap DEBUG + local title_escape="\033]0;" fi + if [[ $* != prompt-command ]]; then + echo -ne "$title_escape$USER@$HOSTNAME ${PWD/#$HOME/~}"; printf "%s" "$*"; echo -ne "\007" + fi + } + + # for titlebar + # condition from the screen man page i think + if [[ $TERM == *(screen*|xterm*|rxvt*) ]]; then + trap 'settitle "$BASH_COMMAND"' DEBUG + else + trap DEBUG + fi fi reset-konsole() { - # we also have a file in /a/c/...konsole... - local f=$HOME/.config/konsolerc - setini DefaultProfile profileian.profile "Desktop Entry" $f - setini Favorites profileian.profile "Favorite Profiles" $f - setini ShowMenuBarByDefault false KonsoleWindow $f - setini TabBarPosition Top TabBar $f + # we also have a file in /a/c/...konsole... + local f=$HOME/.config/konsolerc + setini DefaultProfile profileian.profile "Desktop Entry" $f + setini Favorites profileian.profile "Favorite Profiles" $f + setini ShowMenuBarByDefault false KonsoleWindow $f + setini TabBarPosition Top TabBar $f } reset-sakura() { - while read k v; do - setini $k $v sakura /a/c/subdir_files/.config/sakura/sakura.conf - done <<'EOF' + while read k v; do + setini $k $v sakura /a/c/subdir_files/.config/sakura/sakura.conf + done <<'EOF' colorset1_back rgb(33,37,39 less_questions true audible_bell No @@ -1951,19 +1980,19 @@ EOF } reset-xscreensaver() { - # except for spash, i set these by setting gui options in - # xscreensaver-command -demo - # then finding the corresponding option in .xscreensaver - # spash, i happened to notice in .xscreensaver - cat > /home/iank/.xscreensaver <<'EOF' + # except for spash, i set these by setting gui options in + # xscreensaver-command -demo + # then finding the corresponding option in .xscreensaver + # spash, i happened to notice in .xscreensaver + cat > /home/iank/.xscreensaver <<'EOF' mode: blank dpmsEnabled: True -dpmsStandby: 0:01:00 -dpmsSuspend: 0:01:00 -dpmsOff: 0:02:00 -timeout: 0:01:00 +dpmsStandby: 0:02:00 +dpmsSuspend: 0:02:00 +dpmsOff: 0:03:00 +timeout: 0:02:00 lock: True -lockTimeout: 0:02:00 +lockTimeout: 0:03:00 splash: False EOF @@ -1974,10 +2003,10 @@ EOF # stuff that makes sense to be at the end # ########################################### if [[ "$SUDOD" ]]; then - cd "$SUDOD" - unset SUDOD + cd "$SUDOD" + unset SUDOD elif [[ -d /a ]] && [[ $PWD == $HOME ]] && [[ $- == *i* ]]; then - cd /a + cd /a fi @@ -1987,7 +2016,7 @@ unset IFS # if someone exported $SOE, catch errors if [[ $SOE ]]; then - errcatch + errcatch fi # I'd prefer to have system-wide, plus user ruby, due to bug in it @@ -2007,9 +2036,9 @@ fi export rvmsudo_secure_path=1 if [[ -s "/usr/local/rvm/scripts/rvm" ]]; then - source "/usr/local/rvm/scripts/rvm" + source "/usr/local/rvm/scripts/rvm" elif [[ -s $HOME/.rvm/scripts/rvm ]]; then - source $HOME/.rvm/scripts/rvm + source $HOME/.rvm/scripts/rvm fi export GOPATH=$HOME/go @@ -2032,7 +2061,7 @@ path_add --end ~/.npm-global # i added an extra condition as gentoo xorg guide says depending on # $DISPLAY is fragile. if [[ ! $DISPLAY && $XDG_VTNR == 1 ]] && shopt -q login_shell && isarch; then - exec startx + exec startx fi diff --git a/conflink b/conflink index 38aacf0..ca9fb41 100755 --- a/conflink +++ b/conflink @@ -90,6 +90,7 @@ case $USER in if [[ -e /etc/davpass ]] && getent group www-data &>/dev/null; then s chgrp www-data /etc/davpass fi + /a/exe/lnf -T /p/arbtt-capture.log ~/.arbtt/capture.log ##### end special extra stuff ##### diff --git a/desktop-20-autostart.sh b/desktop-20-autostart.sh index df8dab8..842dab4 100755 --- a/desktop-20-autostart.sh +++ b/desktop-20-autostart.sh @@ -50,11 +50,5 @@ if isarch; then pulseaudio --start fi -/a/exe/lnf -T /p/arbtt-capture.log ~/.arbtt/capture.log -# docs say a sample rate less than 20 is probably not worth the data cost, -# but it seems pretty small to me -arbtt-capture --sample-rate=10 & - - #indicator-kdeconnect date "+%A, %B %d, %r, %S seconds" > /tmp/desktop-20-autostart-log diff --git a/distro-end b/distro-end index 9f06366..8e35839 100755 --- a/distro-end +++ b/distro-end @@ -1501,6 +1501,8 @@ case $distro in debian|trisquel|ubuntu) s gpasswd -a iank adm ;; #needed for reading logs esac +/a/bin/buildscripts/pithosfly + #### tor case $distro in # based on diff --git a/filesystem/etc/X11/Xsession.d/01iank b/filesystem/etc/X11/Xsession.d/01iank new file mode 100644 index 0000000..d32768a --- /dev/null +++ b/filesystem/etc/X11/Xsession.d/01iank @@ -0,0 +1,3 @@ +#!/bin/bash + +install -o iank -g iank -d -m700 /home/iank/gpg-agent-socket diff --git a/filesystem/etc/X11/Xsession.d/98iank b/filesystem/etc/X11/Xsession.d/98iank index 23adf30..506e9bc 100644 --- a/filesystem/etc/X11/Xsession.d/98iank +++ b/filesystem/etc/X11/Xsession.d/98iank @@ -2,5 +2,9 @@ # no screensaver for htpc machine if [[ $HOSTNAME != frodo ]]; then -/usr/share/xscreensaver/xscreensaver-wrapper.sh & + /usr/share/xscreensaver/xscreensaver-wrapper.sh & +fi + +if [[ $HOSTNAME == $MAIL_HOST ]]; then + arbtt-capture --sample-rate=10 & fi diff --git a/filesystem/etc/profile.d/environment.sh b/filesystem/etc/profile.d/environment.sh index 4c5794f..6a1dff0 100644 --- a/filesystem/etc/profile.d/environment.sh +++ b/filesystem/etc/profile.d/environment.sh @@ -14,6 +14,7 @@ export EDITOR="emacsclient" # instead of some alternate editor logic export ALTERNATE_EDITOR="" +export PITHOSFLY_SAVE_DIR=/a/pandora_rips4 # makes subsequent syscalls to localtime use cached timezone, # so basically restart the comp if you change time zones, diff --git a/fsf-get-mail b/fsf-get-mail index ee7caee..16c8d7e 100755 --- a/fsf-get-mail +++ b/fsf-get-mail @@ -6,6 +6,9 @@ # delete based on http://deflexion.com/2006/05/imap-way-of-deleting-message sieve-filter -eW -o mail_location=maildir:/nocow/user/fsfmd:LAYOUT=fs:INBOX=/nocow/user/fsfmd/INBOX ~/sieve/fsf.sieve INBOX delete &>/tmp/fsfsieve.log +# mu indexing happens after this, it gets files that have been moved +# from the above command. So, trying this out to fix it out. +sleep 0.5 # to test new rules, update fsf-test.sieve, run these commands, then copy new fsf-test.sieve to fsf.sieve # sieve-filter -o mail_location=maildir:/nocow/user/fsfmd:LAYOUT=fs:INBOX=/nocow/user/fsfmd/INBOX ~/sieve/fsf-test.sieve INBOX &>/tmp/testfsfsieve.log diff --git a/mail-setup b/mail-setup index a0bba6d..04e9661 100755 --- a/mail-setup +++ b/mail-setup @@ -186,6 +186,18 @@ postconfin() { postconf -ev "${MAPFILE[@]}" } e() { printf "%s\n" "$*"; } +pi() { # package install + local s f + if dpkg -s -- "$@" &> /dev/null; then + return 0; + fi; + while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done + f=/var/cache/apt/pkgcache.bin; + if [[ ! -r $f ]] || (( $(( $(date +%s) - $(stat -c %Y $f ) )) > 60*60*12 )); then + apt-get update + fi + apt-get -y install --purge --auto-remove "$@" +} postmaster=$u mxhost=mail.iankelling.org @@ -234,9 +246,10 @@ postfix postfix/relayhost string $relayhost postfix postfix/root_address string $postmaster EOF if dpkg -s postfix &>/dev/null; then + while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done dpkg-reconfigure -u -fnoninteractive postfix else - apt-get -y install --purge --auto-remove postfix + pi postfix fi else source /a/bin/distro-functions/src/package-manager-abstractions @@ -285,9 +298,7 @@ EOF else # begin exim. has debian specific stuff for now - if ! dpkg -s openvpn &>/dev/null; then - apt-get -y install --purge --auto-remove openvpn - fi + pi openvpn if [[ -e /p/c/filesystem ]]; then # allow failure of these commands when our internet is down, they are likely not needed, @@ -609,8 +620,7 @@ EOF # sieve has the benefit of being supported in postfix and # proprietary/weird environments, so there is more examples on the # internet. I was torn about whether to do this or not, meh. - apt-get -y install --purge --auto-remove \ - dovecot-core dovecot-imapd dovecot-sieve dovecot-lmtpd + pi dovecot-core dovecot-imapd dovecot-sieve dovecot-lmtpd # if we changed 90-sieve.conf and removed the active part of the # sieve option, we wouldn\'t need this, but I\'d rather not modify a @@ -720,6 +730,7 @@ EOF # gotta remove this, otherwise the set-selections are completely # ignored. It woulda been nice if this was documented somewhere! rm -f /etc/exim4/update-exim4.conf.conf + while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done dpkg-reconfigure -u -fnoninteractive exim4-config fi @@ -742,7 +753,7 @@ EOF fi # light version of exim does not have sasl auth support. - apt-get -y install --purge --auto-remove exim4-daemon-heavy spamassassin + pi exim4-daemon-heavy spamassassin diff --git a/mastodon-upgrade b/mastodon-upgrade index 8958f7f..a606049 100755 --- a/mastodon-upgrade +++ b/mastodon-upgrade @@ -6,7 +6,7 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR # based on # https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Docker-Guide.md -[[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@" +if [[ $EUID == 0 ]]; then echo "$0: error, do not run as root"; exit 1; fi cd /home/iank/mastodon git fetch diff --git a/mount-latest-subvol b/mount-latest-subvol index d7be613..36895aa 100644 --- a/mount-latest-subvol +++ b/mount-latest-subvol @@ -82,23 +82,25 @@ fstab() { done } kill-dir() { - found_pids=false - sig=${1:-TERM} - if pids=$(timeout 4 lsof -t $dir); then - found_pids=true - timeout 4 lsof -w $dir - kill -$sig $pids - fi - # fuser will find open sockets that lsof won't, for example from gpg-agent. - # note: -v shows kernel processes, which then doesn't return true when we want - if timeout 4 fuser -m $dir &>/dev/null; then - found_pids=true - fuser -$sig -mvk $dir - fi - if $found_pids; then + for sig; do + echo kill-dir $sig + found_pids=false + if pids=$(timeout 4 lsof -t $dir); then + found_pids=true + timeout 4 lsof -w $dir + kill -$sig $pids + fi + # fuser will find open sockets that lsof won't, for example from gpg-agent. + # note: -v shows kernel processes, which then doesn't return true when we want + if timeout 4 fuser -m $dir &>/dev/null; then + found_pids=true + fuser -$sig -mvk $dir + fi sleep .5 - return 0 - fi + if ! $found_pids; then + return 0 + fi + done return 1 } @@ -192,7 +194,9 @@ for vol in q a o i; do if e umount -R $dir; then unmounted+=($dir) else - kill-dir || kill-dir INT || kill-dir HUP || ! $force || kill-dir KILL ||: + if ! kill-dir TERM TERM TERM INT INT HUP HUP; then + if $force; then kill-dir KILL; fi + fi if e umount -R $dir; then unmounted+=($dir) diff --git a/pkgs b/pkgs index 72ea161..f57b57f 100644 --- a/pkgs +++ b/pkgs @@ -103,6 +103,7 @@ p4=( make-doc manpages manpages-dev + markdown mb2md meld mps-youtube @@ -118,6 +119,7 @@ p4=( p7zip paprefs parted-doc + pass pavucontrol pdfgrep perl-doc diff --git a/radicale-setup b/radicale-setup index 531f1ec..802e0b8 100755 --- a/radicale-setup +++ b/radicale-setup @@ -83,7 +83,6 @@ fi # davdroid from f-druid. # login with url and user name -# username ian, # url https://cal.iankelling.org # username ian # pass, see password manager diff --git a/subdir_files/.gnupg/gpg.conf b/subdir_files/.gnupg/gpg.conf index f45b4ee..8d728b2 100644 --- a/subdir_files/.gnupg/gpg.conf +++ b/subdir_files/.gnupg/gpg.conf @@ -13,9 +13,11 @@ use-agent # another option is 0xshort keyid-format 0xlong + default-key B125F60B7B287FF6A2B7DF8F170AF0E2954295DF -default-key 0xFB40960C541A7D1F +# financial key +#default-key 0xFB40960C541A7D1F # note, i did this so that gpg-agent would not hold open the .gnupg dir. # so I could unmount the filesystem which holds the .gnupg dir while @@ -28,3 +30,6 @@ default-key 0xFB40960C541A7D1F # echo -e "%Assuan%\nsocket=${HOME}/gpg-agent-socket/s" > ~/.gnupg/S.gpg-agent # # this is also in my conflink scrpt: # install -d -m700 ~/gpg-agent-socket +# and in /etc/X11/Xsession.d/01iank +# install -o iank -g iank -d -m700 /home/iank/gpg-agent-socket +# because something keeps deleting that directory diff --git a/switch-mail-host b/switch-mail-host index 9b4872d..8d4072b 100755 --- a/switch-mail-host +++ b/switch-mail-host @@ -125,8 +125,15 @@ for ((i=0; i<10; i++)); do sleep 1 if [[ i == 9 ]]; then warn="WARNING!!! failed to kill arbtt-capture" - fi - done + fi +done +for ((i=0; i<10; i++)); do + $new_shell killall arbtt-capture || break + sleep 1 + if [[ i == 9 ]]; then + warn="WARNING!!! failed to kill arbtt-capture" + fi +done $new_shell bash -s <<'EOF'