shopt -s globstar
-# inside emacs fixes
+# 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
bind 'set print-completions-horizontally on'
bind '"\C-i": self-insert'
else
- # arrow keys. for other terminals, see http://unix.stackexchange.com/questions/10806/how-to-change-previous-next-word-shortcut-in-bash
+ # 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
- # terminal keys: C-c, C-z. the rest defined by stty -a are, at least in
+ # 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 werase undef lnext undef stop undef start undef
-
+ stty lnext undef stop undef start undef
fi
fi
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
+export WCDHOME=/a
# based on readme.debian. dunno if this will break on other distros.
_x=/usr/share/wcd/wcd-include.sh
if [[ -e $_x ]]; then source $_x; fi
_khfix_common() {
local h=${1##*@}
+ local x
ssh-keygen -R $h -f $(readlink -f ~/.ssh/known_hosts)
- local x=$(timeout 0.1 ssh -v $1 |& sed -rn "s/debug1: Connecting to $h \[([^\]*)].*/\1/p");
+ 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 "$@"
+ _khfix_common "$@" || return 1
ssh $1 :
}
khcopy() {
ack() { ack-grep "$@"; }
+anki() {
+ 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
c -
}
-bashrcpush () {
- local startdir="$PWD"
- cd ~
- for x in "$@"; do
- ssh $x mkdir -p bin/distro-functions/src
- 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 .
- for x in "$@"; do
- tar cz * | ssh $x tar xz
- done
- cd "$startdir"
-}
-
bkrun() {
# 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'
+}
+
btc() {
local f=/etc/bitcoin/bitcoin.conf
- bitcoin-cli -$(s grep rpcuser= $f) -$(s grep rpcpassword= $f) "$@"
+ # 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
+}
+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
+}
+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
}
+
+# c. better cd
if [[ $RLC_INSIDE_EMACS ]]; then
- c() { wcd -z 50 -o "$@"; }
+ c() { wcd -c -z 50 -o "$@"; }
else
# lets see what the fancy terminal does from time to time
- c() { wcd -z 50 "$@"; }
+ 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
+
+}
+
calc() { echo "scale=3; $*" | bc -l; }
# no having to type quotes, but also no command history:
clc() {
}
ccat () { # config cat. see a config without extra lines.
- grep '^\s*[^[:space:]#]' "$@"
+ grep '^\s*[^;[:space:]#]' "$@"
}
cdiff() {
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
+}
+
d() { builtin bg; }
complete -A stopped -P '"%' -S '"' d
date "+%A, %B %d, %r" "$@"
}
-dus() {
+dus() { # du, sorted, default arg of
du -sh ${@:-*} | sort -h
}
done < "$file"
}
+# mail related
+etail() {
+ sudo tail -f /var/log/exim4/mainlog
+}
+
f() {
# cd forward
c +
}
faf() { # find all files
- find $@ -type f
+ 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 "$@";
+}
+
+
+# List of apps to install/update
+# Create from existing manually installed apps by doing
+# fdroidcl search -i, then manually removing
+# automatically installed/preinstalled apps
+
+# firefox updater. commented out, firefox depends on nonfree opengl.
+# de.marmaro.krt.ffupdater
+# # causes replicant to die on install and go into a boot loop
+# me.ccrama.redditslide
+#
+# # my attempt at recovering from boot loop:
+# # in that case, boot to recovery (volume up, home button, power, let go of power after samsun logo)
+# # then
+# mount /dev/block/mmcblk0p12 /data
+# cd /data
+# find -iname '*appname*'
+# rm -rf FOUND_DIRS
+# usually good enough to just rm -rf /data/app/APPNAME
+#
+# currently broken:
+#at.bitfire.davdroid
+fdroid_pkgs=(
+ 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
+)
+# 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
+ 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
+}
+
+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"
+}
+fdhome() { #firefox default home profile
+ firefox-default-profile Profile0
}
-fastboot() { /a/opt/androidsdk/platform-tools/fastboot "$@"; }
+fdwork() {
+ firefox-default-profile Profile4
+}
ff() {
if type -P firefox &>/dev/null; then
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
+}
+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[@]}"
+}
+
funce() {
# like -e for functions. returns on error.
# at the end of the function, disable with:
echo "${p%%/.git}"
}
-# quit will prompt if the program crashes.
-gmacs() { gdb -ex=r -ex=quit --args emacs "$@"; r; }
+gitian() {
+ git config user.email ian@iankelling.org
+}
+
+gmacs() {
+ # quit will prompt if the program crashes.
+ gdb -ex=r -ex=quit --args emacs "$@"; r;
+}
+
+gdkill() {
+ # kill the emacs daemon
+ pk1 emacs --daemon
+}
gse() {
git send-email --notes '--envelope-sender=<ian@iankelling.org>' \
}
hr() { # horizontal row. used to break up output
- printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq $COLUMNS)
+ printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq ${COLUMNS:-60})
echo
}
ifn() {
# insensitive find
find -L . -not \( -name .svn -prune -o -name .git -prune \
- -o -name .hg -prune \) -iname "*$**" 2>/dev/null
+ -o -name .hg -prune -o -name .editor-backups -prune \
+ -o -name .undo-tree-history -prune \) -iname "*$**" 2>/dev/null
}
}
fi
+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
+}
istext() {
grep -Il "" "$@" &>/dev/null
journalctl -n 10000 -f "$@" | grep -Evi "^(\S+\s+){4}(sudo|sshd|cron)"
}
+kff() { # keyboardio firmware flash
+ pushd /a/opt/sketches/Model01-Firmware
+ yes $'\n' | make flash
+ popd
+}
l() {
if [[ $PWD == /[iap] ]]; then
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"
+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
}
-
-
-
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"
+ safe_rename "$x" "$y" || return 1
fi
done
}
k() { # history search
- grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 40;
+ grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 80;
+}
+
+ks() { # history search
+ grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | uniq;
}
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
+}
+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
+}
+
+mdt() {
+ markdown -o /tmp/mdtest.html "$1"
+ firefox /tmp/mdtest.html
+}
+
mkc() {
mkdir "$1"
c "$1"
}
+mkt() { # mkdir and touch file
+ local path="$1"
+ mkdir -p "$(dirname "$path")"
+ touch "$path"
+}
+
mkdir() { command mkdir -p "$@"; }
+mo() { xset dpms force off; } # monitor off
+
+otp() {
+ oathtool --totp -b "$@" | xclip -selection clipboard
+}
+
+# pithosfly is broken due to bitrot.
pithos() {
cd /
export PYTHONPATH=/a/opt/Pithosfly
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
+}
+
pick-trash() {
# trash-restore lists everything that has been trashed at or below CWD
# This picks out files just in CWD, not subdirectories,
done
}
-postconfin() {
- local MAPFILE
- mapfile -t
- local s
- [[ $EUID == 0 ]] || s=s
- $s postconf -ev "${MAPFILE[@]}"
-}
+ping8() { ping 8.8.8.8; }
pub() {
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
+}
+
pwgen() {
# -m = min length
apg -m 12 -x 16 -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
+}
+
q() { # start / launch a program in the backround and redir output to null
"$@" &> /dev/null &
}
rlu() { # [OPTS] HOST PATH
- # eg rlu -opts frodo /testpath
+ # 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 echo error: need absolut path; return 1; fi
+ 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
+}
+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
fi
}
+rmstrips() {
+ ssh fencepost head -n 300 /gd/gnuorg/EventAndTravelInfo/rms-current-trips.txt
+}
+
s() {
# background
# I use a function because otherwise we can't use in a script,
fi
}
-safe_rename() {
+safe_rename() { # warn and don't rename if file exists.
+ # mv -n exists, but it's silent
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.
+ 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 "$1" "$2"
+ mv -vi "$1" "$2"
fi
fi
}
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" <<EOF
+# remove existing keys
+/ *\[$section\]/,/^ *\[[^]]+\]/{/^\s*$key[[:space:]=]/d}
+# add key
+/^\s*\[$section\]/a $key=$value
+# from section to eof, do nothing
+/^\s*\[$section\]/,\$b
+# on the last line, if we haven't found section yet, add section and key
+\$a [$section]\\
+$key=$value
+EOF
+ else
+ cat >"$file" <<EOF
+[$section]
+$key=$value
+EOF
+ fi
+}
+
sgo() { # service go
service=$1
- ser restart $service
+ 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
+ # 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 <<EOFOUTER
+#!/bin/bash
+trap "trap - TERM && kill 0" INT TERM ERR; set -e
+( sleep .2; scriptreplay <( cat <<'EOF'
+$(cat $tmp/timing)
+EOF
+) <( cat <<'EOF'
+$(cat $tmp/typescript)
+EOF
+))&
+base64 -d - <<'EOF'| mpv --loop=no --loop-file=no --no-terminal --no-audio-display "\$@" -
+$(base64 "$1")
+EOF
+kill 0
+EOFOUTER
+ rm -r $tmp
+ chmod +x $out
+}
slog() {
# log with script. timing is $1.t and script is $1.s
scriptreplay "$1.t" "$1.s"
}
+spend() {
+ s systemctl suspend
+}
+
sr() {
# sudo redo. be aware, this command may not work right on strange distros or earlier software
if [[ $# == 0 ]]; then
ssh $1 /tmp/${2##*/} "${@:2}"
}
+sss() { # ssh solo
+ 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[@]}" "$@"
+}
+
swap() {
local tmp
tmp=$(mktemp)
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<x; i++)); do
- if (( i % 6 )); then
- echo -n _
- else
- echo -n .
- fi
- done
- if $end; then
- echo
- x=1
+ else
+ rm -rf "$@"
+ fi
+}
+
+
+ tclock() {
+ clear
+ date +%l:%_M
+ len=60
+ # this goes to full width
+ #len=${1:-$((COLUMNS -7))}
+ x=1
+ while true; do
+ if (( x == len )); then
+ end=true
+ d="$(date +%l:%_M) "
+ else
+ end=false
+ d=$(date +%l:%M:%_S)
+ fi
+ echo -en "\r"
+ echo -n "$d"
+ for ((i=0; i<x; i++)); do
+ if (( i % 6 )); then
+ echo -n _
+ else
+ echo -n .
+ fi
+ done
+ if $end; then
+ echo
+ x=1
+ else
+ x=$((x+1))
+ fi
+ sleep 5
+ done
+ }
+
+
+ te() {
+ # test existence / exists
+ local ret=0
+ for x in "$@"; do
+ [[ -e "$x" || -L "$x" ]] || ret=1
+ done
+ return $ret
+ }
+
+ # mail related
+ testmail() {
+ declare -gi _seq; _seq+=1
+ echo "test body" | m mail -s "test mail from $HOSTNAME, $_seq" "${@:-root@localhost}"
+ # for testing to send from an external address, you can do for example
+ # -aFrom:ian@iank.bid web-6fnbs@mail-tester.com
+ # note in exim, you can retry a deferred message
+ # s exim -M MSG_ID
+ # MSG_ID is in /var/log/exim4/mainlog, looks like 1ccdnD-0001nh-EN
+ }
+
+ # to test sieve, use below command. for fsf mail, see fsf-get-mail script.
+ # make modifications, then copy to live file, use -eW to actually modify mailbox
+ # cp /p/c/subdir_files/sieve/personal{test,}.sieve; testsievelist -eW INBOX
+ #
+ # Another option is to use sieve-test SCRIPT MAIL_FILE. note,
+ # sieve-test doesn't know about envelopes, I'm not sure if sieve-filter does.
+
+ # sieve with output filter. arg is mailbox, like INBOX.
+ # This depends on dovecot conf, notably mail_location in /etc/dovecot/conf.d/10-mail.conf
+
+ testsievelist() {
+ sieve-filter ~/sieve/maintest.sieve "$@" >/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
- x=$((x+1))
+ unset PROMPT_COMMAND
+ PS1="\w \$ "
+ set -x
fi
- sleep 5
- done
-}
-
-
-te() {
- # test existence / exists
- local ret=0
- for x in "$@"; do
- [[ -e "$x" || -L "$x" ]] || ret=1
- done
- return $ret
-}
-
-testmail() {
- declare -gi _seq; _seq+=1
- echo "test body" | m mail -s "test mail from $HOSTNAME, $_seq" "${1:-root@localhost}"
-}
-
-tm() {
- # timer in minutes
- (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3 --loop=no) > /dev/null 2>&1 &
-}
-
-ts() { # start editing a new file
- [[ $# != 1 ]] && echo "I need a filename." && return 1
- local quiet
- if [[ $- != *i* ]]; then
- quiet=true
- fi
- if [[ $1 == *.c ]]; then
- e '#include <stdio.h>' >"$1"
- e '#include <stdlib.h>' >>"$1"
- e 'int main(int argc, char * argv[]) {' >>"$1"
- e ' printf( "hello world\n");' >>"$1"
- e ' return 0;' >>"$1"
- e '}' >>"$1"
- e "${1%.c}: $1" > Makefile
- e " g++ -ggdb -std=gnu99 -o ${1%.c} $<" >> Makefile
- e "#!/bin/bash" >run.sh
- e "./${1%.c}" >>run.sh
- chmod +x run.sh
- elif [[ $1 == *.java ]]; then
- e "public class ${1%.*} {" >"$1"
- e ' public static void main(String[] args) {' >>"$1"
- e ' System.out.println("Hello, world!");' >>"$1"
- e ' }' >>"$1"
- e '}' >>"$1"
- else
- echo "#!/bin/bash" > "$1"
- chmod +x "$1"
- fi
- [[ $quiet ]] || g "$1"
-}
-
-
-tu() {
- local s;
- local dir="$(dirname "$1")"
- if [[ -e $1 && ! -w $1 || ! -w $(dirname "$1") ]]; then
- s=s;
- fi
- $s teeu "$@"
-}
-
-tx() { # toggle set -x, and the prompt so it doesn't spam
- if [[ $- == *x* ]]; then
- set +x
- PROMPT_COMMAND=prompt_command
- else
- unset PROMPT_COMMAND
- PS1="\w \$ "
- set -x
- fi
}
psnetns() {
m() { printf "%s\n" "$*"; "$@"; }
+
+vpncmd() {
+ m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/client/client.conf") -n -m "$@"
+}
+vpnf() {
+ vpncmd gksudo -u ian "firefox -no-remote -P firefox-main-profile" &r
+}
vpnbash() {
- m s nsenter -t $(pgrep openvpn) -n -m bash
- # note, if we wanted to run a graphical program,
- # instead of bash, we could use
- # gksudo -u ${SUDO_USER:-$USER} "$@"
+ vpncmd bash
}
-trg() { transmission-remote-gtk&r; }
-
-# transmission() {
-# local pid=$(cat /var/lib/transmission-daemon/transmission-daemon.pid)
-# if [[ $pid && -e /proc/$pid ]]; then
-# echo "noop. already running."
-# return
-# fi
-
-# local NAME=transmission-daemon
-# local DAEMON=/usr/bin/$NAME
-# local duser=debian-transmission
-
-# [ -e /etc/default/$NAME ] && . /etc/default/$NAME
-# s ip netns exec vpn sudo -u $duser ionice -c 3 nice -n 19 $DAEMON $OPTIONS
-# }
virshrm() {
for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done
vm-set-listen $1 127.0.0.1
}
+
vpn() {
- s systemctl start openvpn@client&
- journalctl --unit=openvpn@client -f -n0
-}
+ if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then
+ local vpn_service=openvpn-client
+ else
+ local vpn_service=openvpn
+ fi
+ [[ $1 ]] || { echo need arg; return 1; }
+ journalctl --unit=$vpn_service@$1 -f -n0 &
+ s systemctl start $vpn_service@$1
+ # sometimes the ask-password agent does not work and needs a delay.
+ sleep .5
+ # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779240
+ # noticed around 8-2017 after update from around stretch release
+ # on debian testing, even though the bug is much older.
+ s systemd-tty-ask-password-agent
+}
vpnoff() {
- s systemctl stop openvpn@client
+ [[ $1 ]] || { echo need arg; return 1; }
+ if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then
+ local vpn_service=openvpn-client
+ else
+ local vpn_service=openvpn
+ fi
+ s systemctl stop $vpn_service@$1
}
}
-whatismyip() { curl ipecho.net/plain ; echo; }
+wtr() { curl wttr.in/boston; }
+xl() {
+ if pgrep gnome-screensav &>/dev/null; then
+ # this command actually starts gnome-screensaver if it isn't running.
+ # lololol, what crap
+ gnome-screensaver-command --exit &>/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
+}
#############################
######### misc stuff ########
#############################
+# 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
+}
+complete -F _cheatsh_complete_curl curl
+
+
if [[ $- == *i* ]]; then
# commands to run when bash exits normally
trap "hl" EXIT
PS1="\h $PS1"
fi
- prompt_command() {
+
+
+
+ prompt-command() {
local return=$? # this MUST COME FIRST
local psc pst ps_char ps_color stale_subvol
unset IFS
history -a # save history
- # for titlebar
- if [[ ! $DESKTOP_SESSION == xmonad && $TERM == *(screen*|xterm*|rxvt*) ]]; then
- # from the screen man page
- if [[ $TERM == screen* ]]; then
- local title_escape="\033]..2;"
- else
- local title_escape="\033]0;"
- fi
- echo -ne "$title_escape${PWD/#$HOME/~} $USER@$HOSTNAME\007"
- fi
case $return in
# 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
+ 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
+ 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
+}
+
+reset-sakura() {
+ 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
+visible_bell No
+disable_numbered_tabswitch true
+scroll_lines 10000000
+scrollbar true
+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'
+mode: blank
+dpmsEnabled: True
+dpmsStandby: 0:01:00
+dpmsSuspend: 0:01:00
+dpmsOff: 0:02:00
+timeout: 0:01:00
+lock: True
+lockTimeout: 0:02:00
+splash: False
+EOF
+
+}
###########################################
# based on warning from rvmsudo
export rvmsudo_secure_path=1
-# for other script I wrote
-#export ACME_TINY_PATH=/a/opt/acme-tiny
-export ACME_TINY_WRAPPER_CERT_DIR=/p/c/machine_specific/$HOSTNAME/webservercerts
-
if [[ -s "/usr/local/rvm/scripts/rvm" ]]; then
source "/usr/local/rvm/scripts/rvm"
elif [[ -s $HOME/.rvm/scripts/rvm ]]; then
source $HOME/.rvm/scripts/rvm
fi
+export GOPATH=$HOME/go
+path_add $GOPATH/bin
+
+export ARDUINO_PATH=/a/opt/Arduino/build/linux/work
path_add --end ~/.npm-global