fi
fi
-# based on readme.debian. dunno if this will break on other distros.
-if [[ -s /usr/share/wcd/wcd-include.sh ]]; then
- source /usr/share/wcd/wcd-include.sh
-fi
-
mysrc() {
local path dir file
done
-b() {
- # backwards
- c -
-}
-
hexipv4() {
printf '%d.%d.%d.%d\n' $(echo $1 | sed 's/../0x& /g')
}
echo "print( ($1 $(date +%z | sed -r 's/..$//;s/^(-?)0*/\1/')) % 24)"|python3
}
-# c. better cd
-if type -p wcd &>/dev/null; then
- if [[ $LC_INSIDE_EMACS ]]; then
- c() { wcd -c -z 50 -o "$@"; }
- else
- # lets see what the fancy terminal does from time to time
- c() { wcd -c -z 50 "$@"; }
+declare -a _iankdirf _iankdirb
+
+
+# ## old wcd, to be deleted
+# b() {
+# # backwards
+# c -
+# }
+# # shellcheck disable=SC2032
+# f() {
+# # cd forward
+# c +
+# }
+# cl() {
+# # choose recent directory. cl = cd list
+# c =
+# }
+# # c. better cd
+# if ! type -t c &>/dev/null; then
+# if type -p wcd &>/dev/null; then
+# if [[ $LC_INSIDE_EMACS ]]; then
+# c() { wcd -c -z 50 -o "$@"; }
+# else
+# # lets see what the fancy terminal does from time to time
+# c() { wcd -c -z 50 "$@"; }
+# fi
+# else
+# c() { cd "$@"; }
+# fi
+# fi
+
+# c. better cd.
+# keep 2 stacks, forward and back. the top of the back is $PWD
+# as long as the last directory change was due to c,b,or cl.
+c() {
+ # normally, the top of dirb is our current dir. if it isn't,
+ # put it on there, except we don't want to do that when we
+ # just launched a shell
+ if [[ $OLDPWD ]]; then
+ if (( ${#_iankdirb[@]} == 0 )) || [[ ${_iankdirb[-1]} != "$PWD" ]]; then
+ _iankdirb+=("$PWD")
+ fi
fi
-else
- c() { cd "$@"; }
-fi
+ cd "$@"
+ if (( ${#_iankdirb[@]} == 0 )) || [[ ${_iankdirb[-1]} != "$PWD" ]]; then
+ _iankdirb+=("$PWD")
+ fi
+ echo "$PWD" >> ~/.iankdirs
+}
ccomp cd c
+bwm() {
+ s bwm-ng -T avg -d
+}
+
+b() {
+ local topb
+ if (( ${#_iankdirb[@]} == 0 )); then
+ echo "nothing left to go back to" >&2
+ return 0
+ fi
+ topb="${_iankdirb[-1]}"
+
+ if [[ $topb == "$PWD" ]] && (( ${#_iankdirb[@]} == 1 )); then
+ echo "already on last back entry" >&2
+ return 0
+ fi
+
+
+ if [[ $topb == "$PWD" ]]; then
+ # add to dirf if not already there
+ if (( ${#_iankdirf[@]} == 0 )) || [[ ${_iankdirf[-1]} != "$topb" ]]; then
+ _iankdirf+=("$topb")
+ fi
+ unset "_iankdirb[-1]"
+ cd "${_iankdirb[-1]}"
+ else
+ if (( ${#_iankdirf[@]} == 0 )) || [[ ${_iankdirf[-1]} != "$PWD" ]]; then
+ _iankdirf+=("$PWD")
+ fi
+ cd "$topb"
+ fi
+
+ # give us a peek at what is next in the list
+ # if (( ${#_iankdirb[@]} >= 2 )); then
+ # printf "%s\n" "${_iankdirb[-2]}"
+ # fi
+}
+
+f() {
+ local topf
+ if (( ${#_iankdirf[@]} == 0 )); then
+ echo "no forward dir left" >&2
+ return 0
+ fi
+ topf="${_iankdirf[-1]}"
+ unset "_iankdirf[-1]"
+ c "$topf"
+
+ # give us a peek at what is next in the list
+ # if (( ${#_iankdirf[@]} )); then
+ # printf "%s\n" "${_iankdirf[-1]}"
+ # fi
+}
+
+# a b c (d)
+## back
+# a b (c)
+# d
+#back
+#a (b)
+#d c
+#back
+#(a)
+#d c b
+#forward
+#a (b)
+#d c
+#
+# a b c
+## back
+# a b
+# (c)
+## forward
+
+cl() {
+ local i line input start tmpfile
+ local -A buttondirs alines
+ local -a buttons dirs lines
+ buttons=( {a..z} {2..9} )
+ if [[ ! -s ~/.iankdirs ]]; then
+ echo nothing in ~/.iankdirs
+ return 0
+ fi
+
+ i=0
+
+ # note, alternate approach like this, made the following read fail
+ # done < <(tac ~/.iankdirs | awk '!seen[$0]++')
+ # bash: read: read error: 0: Input/output error
+ # which went away by adding a sleep 1 after it.
+
+ mapfile -t lines <~/.iankdirs
+ start=$(( ${#lines[@]} - 1 ))
+
+ # we have ~33 buttons as of this writing, so lets
+ # prune down the history every once in a while.
+ if (( start > 500 )); then
+ tmpfile=$(mktemp)
+ tac ~/.iankdirs | awk '!seen[$0]++' | head -n 200 >$tmpfile
+ cat $tmpfile > ~/.iankdirs
+ fi
+
+ for (( j=$start; j >= 0; j-- )); do
+ line="${lines[$j]}"
+ if [[ ! $line || ${alines[$line]} || ! -d "$line" || $line == "$PWD" || line == "$HOME" ]]; then
+ continue
+ fi
+ alines[$line]=t
+ buttondirs[${buttons[i]}]="$line"
+ printf "%s %s\n" ${buttons[i]} "$line"
+ if (( i == ${#buttons[@]} - 1 )); then
+ break
+ fi
+ i=$(( i + 1 ))
+ done
+
+ if (( i == 0 )); then
+ echo "no dirs in ~/.iankdirs"
+ return 0
+ fi
+ read -r -N 1 input
+ if [[ $input != $'\n' ]]; then
+ c ${buttondirs[$input]}
+ fi
+}
+bl() {
+ local start i j max
+ max=10
+ start=$(( ${#_iankdirb[@]} - 1 ))
+
+ # cleanup possible repeating of pwd
+ if (( start >= 0 )) && [[ ${_iankdirb[$start]} == "$PWD" ]]; then
+ start=$(( start - 1 ))
+ fi
+ j=1
+ if (( start >= 0 )); then
+ for (( i=$start; i >= 0 ; i-- )); do
+ printf "%s %s\n" $j ${_iankdirb[i]}
+ j=$(( j + 1 ))
+ if (( j >= max )); then
+ break
+ fi
+ done
+ fi
+
+ max=10
+
+ start=$(( ${#_iankdirf[@]} - 1 ))
+
+ # cleanup possible repeating of pwd
+ if (( start >= 0 )) && [[ ${_iankdirf[$start]} == "$PWD" ]]; then
+ start=$(( start - 1 ))
+ fi
+ if (( start < 0 )); then
+ return 0
+ fi
+ echo --
+ j=1
+ for (( i=$start; i >= 0 ; i-- )); do
+ printf "%s %s\n" $j ${_iankdirf[i]}
+ j=$(( j + 1 ))
+ if (( j >= max )); then
+ break
+ fi
+ done
+}
+
+
+
c4() { c /var/log/exim4; }
caa() { git commit --amend --no-edit -a; }
chumount() {
local d
# dev/pts needed for pacman signature check
- for d in dev proc sys dev/pts; do
+ for d in dev/pts dev proc sys; do
[[ -d $d ]]
if mountpoint $d &>/dev/null; then
m s umount $d
cat-new-files() {
local start=$SECONDS
local dir="$1"
- inotifywait -m "$dir" -e create -e moved_to |
- # shellcheck disable=SC2030
+ # shellcheck disable=SC2030
+ inotifywait -m "$dir" -e create -e moved_to | \
while read -r filedir _ file; do
cat "$filedir$file"
hr
git commit -m "$*"
}
-cl() {
- # choose recent directory. cl = cd list
- c =
-}
d() { builtin bg "$@"; }
ccomp bg d
done
}
+# get ipv4 ip from HOST. or if it is already a number, return that
+hostip() {
+ local host="$1"
+ case $host in
+ [0-9:])
+ echo "$host"
+ ;;
+ *)
+ getent ahostsv4 "$host" | awk '{ print $1 }' | head -n1
+ ;;
+ esac
+}
+
dig() {
command dig +nostats +nocmd "$@"
}
dt() {
date "+%A, %B %d, %r" "$@"
}
-ccomp date dt
+dtr() {
+ date -R "$@"
+}
+ccomp date dt dtr
dus() { # du, sorted, default arg of
du -sh ${@:-*} | sort -h
ccomp du dus
-e() { echo "$@"; }
+e() { printf "%s\n" "$*"; }
# echo args
ea() {
etail() {
tail -F /var/log/exim4/mainlog -n 200 "$@"
}
-ccomp tail etail
+etail2() {
+ tail -F /var/log/exim4/mymain -n 200 "$@"
+}
+
+ccomp tail etail etail2
# print exim old pids
eoldpids() {
}
ccomp less eless
eqcat() {
- exiqgrep -i -o 60 | while read -r i; do
+ exiqgrep -ir.\* -o 60 | while read -r i; do
hlm exim -Mvc $i
echo
hlm exigrep $i /var/log/exim4/mainlog | cat ||:
done
}
eqrmf() {
- exiqgrep -i | xargs exim -Mrm
+ # other ways to get the list of message ids:
+ # exim -bp | awk 'NF == 4 {print $3}'
+ # # this is slower 160ms, vs 60.
+ # exipick -i
+ exiqgrep -ir.\* | xargs exim -Mrm
}
econfdevnew() {
-# shellcheck disable=SC2032
-f() {
- # cd forward
- c +
-}
fa() {
# find array. make an array of file names found by find into $x
-o -name .undo-tree-history -prune \) -type f 2>/dev/null
}
-# todo: id like to do maybe a daily or hourly cronjob to
-# check that my history file size is increasing. Ive had it
-# inexplicably truncated in the past.
-histrm() {
- history -n
- history | awk -v IGNORECASE=1 '{ a=$1; sub(/^( *[^ ]+){4} */, "") }; /'"$*"'/'
- read -p "press anything but contrl-c to delete"
- for entry in $(history | awk -v IGNORECASE=1 '{ a=$1; sub(/^( *[^ ]+){4} */, "") }; /'"$*"'/ { print a }' | tac); do
- history -d $entry
- done
- history -w
+# full path without resolving symlinks
+fp() {
+ local dir base
+ base="${1##*/}"
+ dir="${1%$base}"
+ printf "%s/%s\n" $(cd $dir; pwd) "$base"
}
+
# mail related
frozen() {
rm -rf /tmp/frozen
ifn() {
# insensitive find
+ # -L = follow symlinks
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
fi
f="${arg##*/}"
new="${f,,}" # downcase
- new="${new//[^[:alnum:]._-]/_}" # sub bad chars
+ new="${new//[^a-zA-Z0-9._-]/_}" # sub bad chars
new="${new#"${new%%[[:alnum:]]*}"}" # remove leading/trailing non-alnum
new="${new%"${new##*[[:alnum:]]}"}"
# remove bad underscores, like __ and _._
k() { # history search
grep -iP --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 80 || [[ $? == 1 ]];
}
-ks() { # history search
+ks() { # history search with context
+ # args are an extended regex used by sed
+ history | sed -nr "h;s/^\s*(\S+\s+){4}//;/$*/{g;p}" | tail -n 80 || [[ $? == 1 ]];
+}
+ksu() { # history search unique
grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | uniq || [[ $? == 1 ]];
}
-ccomp grep k ks
+
+# todo: id like to do maybe a daily or hourly cronjob to
+# check that my history file size is increasing. Ive had it
+# inexplicably truncated in the past.
+histrm() {
+ history -n
+ HISTTIMEFORMAT= history | awk -v IGNORECASE=1 '{ a=$1; sub(/^ *[^ ]+ */, "") }; /'"$*"'/'
+ read -p "press anything but contrl-c to delete"
+ for entry in $(HISTTIMEFORMAT= history | awk -v IGNORECASE=1 '{ a=$1; sub(/^ *[^ ]+ */, "") }; /'"$*"'/ { print a }' | tac); do
+ history -d $entry
+ done
+ history -w
+}
+
+ccomp grep k ks ksu histrm
make-targets() {
}
nmt() {
- s nmtui-connect "$@"
+ # cant use s because sudo -i doesnt work for passwordless sudo command
+ case $EUID in
+ 0)
+ sudo nmtui-connect "$@"
+ ;;
+ *)
+ nmtui-connect "$@"
+ ;;
+ esac
}
nopanic() {
grep '^ *hosts:' /etc/nsswitch.conf
if systemctl is-enabled systemd-resolved &>/dev/null || [[ $(systemctl is-active systemd-resolved ||:) != inactive ]]; then
hr; m ser status systemd-resolved | cat || :
- hr; m systemd-resolve --status | cat
+ hr; m resolvectl status | cat
fi
}
sk() {
- # note, if you do something like this
- # x=( prefix* )
- # then disable the warning with:
- # shellcheck disable=SC2206 # globbing is intended
-
- # 2029: "unescaped, this expands on the client side.": yes, I know how ssh works
- # 2164: "Use 'cd ... || exit' or 'cd ... || return' in case cd fails.": i have automatic error handling
- # 2086: unquoted $var: Quoting every var I set is way too much quotes.
- # 2068: Double quote array expansions to avoid re-splitting elements: same as above.
- # 2033: command arg is a function name: too many false positives.
-
+ # disable a warning with:
+ # shellcheck disable=SC2206 # reasoning
- # these ones I had disabled, but without a good written explanation, so enabling them temporarily
- # 2046: unquoted $(cmd)
- # 2119: Functions with optional args get bad warnings when none are passed.
+ # see bash-template/style-guide.md for justifications
- shellcheck -W 999 -x -e 2029,2164,2086,2068,2033 "$@" || return $?
+ local quotes others
+ quotes=2048,2068,2086,2206
+ others=2029,2033,2054,2164
+ shellcheck -W 999 -x -e $quotes,$others "$@" || return $?
}
"|sort -r
}
+# Run script by copying it to a temporary location first,
+# and changing directory, so we don't have any open
+# directories or files that could cause problems when
+# remounting.
+z() {
+ local tmp
+ tmp=$(type -p "$1")
+ if [[ $tmp ]]; then
+ cd $(mktemp -d)
+ cp -a "$tmp" .
+ shift
+ ./"${tmp##*/}" "$@"
+ else
+ "$@"
+ fi
+}
+
# * misc stuff