# recommended by the manual.
filters = DateTime
-# copied docs of use_prototypes:
-# p { foo => 1 }; # works, but now p(@foo) will fail, you must always pass a ref,
-# e.g. p(\@foo)
-# end docs. Looking in the source code,
-# we don't need reference for single arguments. But
-# beware that lists automatically become multiple arguments.
-use_prototypes = 0
caller_info = 1
scalar_quotes = '
-string_max = 400000
+string_max = 250
array_max = 400
hash_max = 400
-string_overflow = (.IANK-DDP.. __SKIPPED__ chars...)
+string_overflow = (.DDP.. __SKIPPED__ chars...)
+
+### settings I thought better of.
+# allows a few less characters for anonymous references & avoids some
+#possibility of autovivification. However, it makes everything passed to
+#p needing to be a reference, which is a huge pain when debugging.
+#use_prototypes = 0
+
+## copied examples of how to print anonymous references:
+# p %{{ foo => 1 }}; # right
+# p { foo => 1 }->%*; # right on perl 5.24+
+# &p( { foo => 1 } ); # right, but requires the parenthesis
+# sub pp { p @_ }; # wrapping it also lets you use anonymous data. iank: but it prints extra ugly symbols.
email = iank@fsf.org
#email = ian@iankelling.org
[alias]
-lg = log --graph
-lgstat = log --stat --graph --pretty=format:'%h %ad- %s [%an]'
+lg = log --graph --follow
+lgstat = log --stat --graph --follow --pretty=format:'%h %ad- %s [%an]'
co = checkout
s = status
ci = commit
-lol = log --graph --pretty=oneline --abbrev-commit --all
+lol = log --graph --follow --pretty=oneline --abbrev-commit --all
dt = difftool
# https://stackoverflow.com/questions/17369254/is-there-a-way-to-cause-git-reflog-to-show-a-date-alongside-each-entry
rl = reflog --format='%C(auto)%h %<|(17)%gd %C(blue)%ci%C(reset) %s'
# on git pull of coreboot:
# warning: inexact rename detection was skipped due to too many files.
# warning: you may want to set your diff.renameLimit variable to at least 3694 and retry the command.
-renameLimit = 50000
-renames = copy
+renameLimit = 999999
+ renames = true
[gitreview]
username = iank
# https://stackoverflow.com/questions/70663523/the-unauthenticated-git-protocol-on-port-9418-is-no-longer-supported
[url "https://github.com/"]
insteadOf = git://github.com/
+[merge]
+ renames = true
+ renameLimit = 999999
-PATH="/home/iank/perl5/bin${PATH:+:${PATH}}"; export PATH;
-PERL5LIB="/home/iank/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
-PERL_LOCAL_LIB_ROOT="/home/iank/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
-PERL_MB_OPT="--install_base \"/home/iank/perl5\""; export PERL_MB_OPT;
-PERL_MM_OPT="INSTALL_BASE=/home/iank/perl5"; export PERL_MM_OPT;
-
-
# Useful info. see man bash.
PS4='$LINENO+ '
mysrc /a/bin/distro-functions/src/package-manager-abstractions
mysrc /a/bin/fai/fai/config/distro-install-common/bash-misc-funcs
-# things to remember:
-# ALT-C - cd into the selected directory
-# CTRL-T - Paste the selected file path into the command line
-#
-# good guide to some of its basic features is the readme file
-# https://github.com/junegunn/fzf
-
-# if [[ -s /usr/share/doc/fzf/examples/key-bindings.bash ]]; then
-# source /usr/share/doc/fzf/examples/key-bindings.bash
-# fi
-# this looks more interesting for more easily selecting multiple files:
-# https://github.com/peco/peco?tab=readme-ov-file#keymaps
-# This also looks like it could be customized more than fzf:
-# https://github.com/lotabout/skim
# * aliases
z() { builtin fg "$@"; }
ccomp fg z
-# quick kill.
-x() { builtin kill %%; }
+# kill just the "current" job.
+k1() { builtin kill %%; }
+
+# gracefully kill all jobs
+x() {
+ local -a arr jspecs
+ local l
+ mapfile -t arr <<<$(jobs)
+ for l in "${arr[@]}"; do
+ [[ ${l:1:1} == [0-9] ]] || continue
+ l="${l:1}"
+ jspecs+=(%${l%%[^0-9]*})
+ done
+ (( ${#jspecs[@]} )) || return 1
+ m kill -INT ${jspecs[@]}
+}
+
# diff content, aka word diff.
dc() {
# echo args verbosely
eav() {
+ local arg
+ local -i i=0
+ if (( ! $# )); then
+ echo no args
+ fi
+ for arg; do
+ printf "%d '%q'\n" "$i" "${arg}"
+ i+=1
+ done
+}
+
+# echo args double verbose: adds hexdump.
+eavv() {
+ local arg
+ local -i i=0
if (( ! $# )); then
echo no args
fi
for arg; do
- printf "%qEOL\n" "${arg}"
+ printf "%d '%q'\n" "$i" "${arg}"
printf "%s" "${arg}" |& hexdump -C
+ i+=1
done
}
+
# echo variables. print var including escapes, etc, like xxd for variable
ev() {
+ local arg
+ local -i i=0
if (( ! $# )); then
echo no args
fi
shellcheck -e $quotes,$others "$@" || return $?
}
# wrapper for shellcheck with better defaults.
-sk() {
+shk() {
# see https://savannah.gnu.org/maintenance/fsf/bash-style-guide/ for justifications
local quotes others
local -i ret=0
# shellcheck disable=SC2790 disable=SC2012 # intentional
ls -Uq "$@"|wc -l
}
+### rename, remove earlier name after migration.
+lc() {
+ # shellcheck disable=SC2790 disable=SC2012 # intentional
+ ls -Uq "$@"|wc -l
+}
# count files recursively
fndwc() {
- find -L "$@" -type f -printf a | wc -c
+ local -i total count
+ for d; do
+ count=$(find -L "$d" -type f -printf a | wc -c)
+ total+=$count
+ e "$count $d "
+ done
+ if (( total > count )); then
+ e "total $total"
+ fi
}
# run then notify. close notification after the next prompt.
# all the lines will be joined and stored in $x.
jl() {
x=$(cat)
+}
+
+jrm() {
+ local x
+ x=$(cat)
+ rm -I $x
+}
+
+# Usage LIST_OF_PERL_VARS
+perlpgen() {
+ local var out space_regex=' ' info_text
+ if [[ $1 == -i ]]; then
+ info_text="$2"
+ shift 2
+ elif [[ $1 =~ $space_regex ]]; then
+ info_text="$1"
+ shift
+ fi
+ if [[ $info_text ]]; then
+ info_text=", as => '$info_text'"
+ fi
+ for var; do
+ out+="$var => \$$var, "
+ done
+ jc echo "p { $out}->%*$info_text;"
+}
+
+dtsort() {
+ local daystart
+ daystart=$(date -d 00:00 +%s)
+ day_mins=$(( ( EPOCHSECONDS - daystart ) / 60 ))
+ echo $(date +%j)---$day_mins
}
# * stuff that makes sense to be at the end
# ensure no bad programs appending to this file will have an affect
return 0
+
+
+## just dumping this useful code
+# sleep 100 &
+# pid=$!
+# job_num=$(jobs -l | awk -v pid="$pid" '$2 == pid {gsub(/[\[\]+-]/, "", $1); print $1}')
#path_add --ifexists --end /a/opt/scancode-toolkit-3.10.
path_add --ifexists --end /p/bin
+### stuff recommended by CPAN. However it is quite annoying that these things blindly
+# add on to existing vars, so if you source this file multiple times, you get crazy long vars.
+# So, I fix.
+path_add --end /home/iank/perl5/bin
+if [[ ! $PERL5LIB ]]; then
+ PERL5LIB=/home/iank/perl5/lib/perl5
+ PERL_LOCAL_LIB_ROOT=/home/iank/perl5
+ PERL_MB_OPT="--install_base \"/home/iank/perl5\""
+ PERL_MM_OPT=INSTALL_BASE=/home/iank/perl5
+ export PERL5LIB PERL_LOCAL_LIB_ROOT PERL_MB_OPT PERL_MM_OPT
+fi
+
case $HOSTNAME in
sy|bo)
# https://askubuntu.com/questions/1254544/vlc-crashes-when-opening-any-file-ubuntu-20-04
}
fi
+export I2X_SORT_ORDER=path_desc
+
# * include files
userid=23cc2eb9-e35e-4811-a0f0-d5f0dd6eb634
while read -r rating path; do
cpath="/i/converted${path#/i/m}" # converted path
- case $cpath in
- *.flac)
- cpath="${cpath%.*}.mp3"
- ;;
- esac
+ if [[ $cpath == *.flac ]]; then
+ cpath="${cpath%.*}.mp3"
+ fi
if [[ ! -e $cpath ]]; then
echo "beetraing: error: this should not happen, path does not exist: $cpath"
return 1
}
bindpush() {
- dsign iankelling.org expertpathologyreview.com zroe.org amnimal.ninja
+ dsign iankelling.org zroe.org amnimal.ninja
lipush
for h in li bk; do
m ssh iank@$h.b8.nz dnsup
# mpv profile e. good for videos
mpe () {
mpv --profile=e "$@";
- }
+}
mpva() {
mpv --profile=a "$@";
}
fi
-# ensure no bad programs appending to this file will have an affect
-return 0
-
# finding the letter pages that have hardly any text due to overflow:
letter-hac-fsf() {
{words += NF}
END {print words, page}' ISAL.txt | sort -n
}
+
+
+# things to remember:
+# ALT-C - cd into the selected directory
+# CTRL-T - Paste the selected file path into the command line
+#
+# good guide to some of its basic features is the readme file
+# https://github.com/junegunn/fzf
+
+path_add --end --ifexists /a/opt/fzf/bin
+
+if ! type -p fzf &>/dev/null; then
+ return 0
+fi
+
+##### this is from output of fzf --bash plus a small modification to
+# prevent a command from reporting a superflous nonzero exit, search for
+# iank below.
+
+### key-bindings.bash ###
+# ____ ____
+# / __/___ / __/
+# / /_/_ / / /_
+# / __/ / /_/ __/
+# /_/ /___/_/ key-bindings.bash
+#
+# - $FZF_TMUX_OPTS
+# - $FZF_CTRL_T_COMMAND
+# - $FZF_CTRL_T_OPTS
+# - $FZF_CTRL_R_COMMAND
+# - $FZF_CTRL_R_OPTS
+# - $FZF_ALT_C_COMMAND
+# - $FZF_ALT_C_OPTS
+
+if [[ $- =~ i ]]; then
+
+
+ # Key bindings
+ # ------------
+
+ #----BEGIN shfmt
+ #----BEGIN INCLUDE common.sh
+ # NOTE: Do not directly edit this section, which is copied from "common.sh".
+ # To modify it, one can edit "common.sh" and run "./update.sh" to apply
+ # the changes. See code comments in "common.sh" for the implementation details.
+
+ __fzf_defaults() {
+ printf '%s\n' "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
+ command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
+ printf '%s\n' "${FZF_DEFAULT_OPTS-} $2"
+ }
+
+ __fzf_exec_awk() {
+ if [[ -z ${__fzf_awk-} ]]; then
+ __fzf_awk=awk
+ if [[ $OSTYPE == solaris* && -x /usr/xpg4/bin/awk ]]; then
+ __fzf_awk=/usr/xpg4/bin/awk
+ elif command -v mawk > /dev/null 2>&1; then
+ local n x y z d
+ IFS=' .' read -r n x y z d <<< $(command mawk -W version 2> /dev/null)
+ [[ $n == mawk ]] && ((d >= 20230302 && (x * 1000 + y) * 1000 + z >= 1003004)) && __fzf_awk=mawk
+ fi
+ fi
+ LC_ALL=C exec "$__fzf_awk" "$@"
+ }
+ #----END INCLUDE
+
+ __fzf_select__() {
+ FZF_DEFAULT_COMMAND=${FZF_CTRL_T_COMMAND:-} \
+ FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=file,dir,follow,hidden --scheme=path" "${FZF_CTRL_T_OPTS-} -m") \
+ FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) "$@" |
+ while read -r item; do
+ printf '%q ' "$item" # escape special chars
+ done
+ }
+
+ __fzfcmd() {
+ [[ -n ${TMUX_PANE-} ]] && { [[ ${FZF_TMUX:-0} != 0 ]] || [[ -n ${FZF_TMUX_OPTS-} ]]; } &&
+ echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf"
+ }
+
+ fzf-file-widget() {
+ local selected="$(__fzf_select__ "$@")"
+ READLINE_LINE="${READLINE_LINE:0:READLINE_POINT}$selected${READLINE_LINE:READLINE_POINT}"
+ READLINE_POINT=$((READLINE_POINT + ${#selected}))
+ }
+
+ __fzf_cd__() {
+ local dir
+ dir=$(
+ FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} \
+ FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path" "${FZF_ALT_C_OPTS-} +m") \
+ FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd)
+ ) && printf 'builtin cd -- %q' "$(builtin unset CDPATH && builtin cd -- "$dir" && builtin pwd)"
+ }
+
+ if command -v perl > /dev/null; then
+ __fzf_history__() {
+ local output script
+ script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; s/\n/\n\t/gm; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
+ output=$(
+ set +o pipefail
+ builtin fc -lnr -2147483648 |
+ last_hist=$(HISTTIMEFORMAT='' builtin history 1) command perl -n -l0 -e "$script" |
+ FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '"$'\t'"↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} +m --read0") \
+ FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) --query "$READLINE_LINE"
+ ) || return
+ READLINE_LINE=$(command perl -pe 's/^\d*\t//' <<< "$output")
+ if [[ -z $READLINE_POINT ]]; then
+ echo "$READLINE_LINE"
+ else
+ READLINE_POINT=0x7fffffff
+ fi
+ }
+ else # awk - fallback for POSIX systems
+ __fzf_history__() {
+ local output script
+ [[ $(HISTTIMEFORMAT='' builtin history 1) =~ [[:digit:]]+ ]] # how many history entries
+ script='function P(b) { ++n; sub(/^[ *]/, "", b); if (!seen[b]++) { printf "%d\t%s%c", '$((BASH_REMATCH + 1))' - n, b, 0 } }
+ NR==1 { b = substr($0, 2); next }
+ /^\t/ { P(b); b = substr($0, 2); next }
+ { b = b RS $0 }
+ END { if (NR) P(b) }'
+ output=$(
+ set +o pipefail
+ builtin fc -lnr -2147483648 2> /dev/null | # ( $'\t '<lines>$'\n' )* ; <lines> ::= [^\n]* ( $'\n'<lines> )*
+ __fzf_exec_awk "$script" | # ( <counter>$'\t'<lines>$'\000' )*
+ FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '"$'\t'"↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} +m --read0") \
+ FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) --query "$READLINE_LINE"
+ ) || return
+ READLINE_LINE=${output#*$'\t'}
+ if [[ -z $READLINE_POINT ]]; then
+ echo "$READLINE_LINE"
+ else
+ READLINE_POINT=0x7fffffff
+ fi
+ }
+ fi
+
+ # Required to refresh the prompt after fzf
+ bind -m emacs-standard '"\er": redraw-current-line'
+
+ bind -m vi-command '"\C-z": emacs-editing-mode'
+ bind -m vi-insert '"\C-z": emacs-editing-mode'
+ bind -m emacs-standard '"\C-z": vi-editing-mode'
+
+ if ((BASH_VERSINFO[0] < 4)); then
+ # CTRL-T - Paste the selected file path into the command line
+ if [[ ${FZF_CTRL_T_COMMAND-x} != "" ]]; then
+ bind -m emacs-standard '"\C-t": " \C-b\C-k \C-u`__fzf_select__`\e\C-e\er\C-a\C-y\C-h\C-e\e \C-y\ey\C-x\C-x\C-f\C-y\ey\C-_"'
+ bind -m vi-command '"\C-t": "\C-z\C-t\C-z"'
+ bind -m vi-insert '"\C-t": "\C-z\C-t\C-z"'
+ fi
+
+ # CTRL-R - Paste the selected command from history into the command line
+ if [[ ${FZF_CTRL_R_COMMAND-x} != "" ]]; then
+ if [[ -n ${FZF_CTRL_R_COMMAND-} ]]; then
+ echo "warning: FZF_CTRL_R_COMMAND is set to a custom command, but custom commands are not yet supported for CTRL-R" >&2
+ fi
+ bind -m emacs-standard '"\C-r": "\C-e \C-u\C-y\ey\C-u`__fzf_history__`\e\C-e\er"'
+ bind -m vi-command '"\C-r": "\C-z\C-r\C-z"'
+ bind -m vi-insert '"\C-r": "\C-z\C-r\C-z"'
+ fi
+ else
+ # CTRL-T - Paste the selected file path into the command line
+ if [[ ${FZF_CTRL_T_COMMAND-x} != "" ]]; then
+ bind -m emacs-standard -x '"\C-t": fzf-file-widget'
+ bind -m vi-command -x '"\C-t": fzf-file-widget'
+ bind -m vi-insert -x '"\C-t": fzf-file-widget'
+ fi
+
+ # CTRL-R - Paste the selected command from history into the command line
+ if [[ ${FZF_CTRL_R_COMMAND-x} != "" ]]; then
+ if [[ -n ${FZF_CTRL_R_COMMAND-} ]]; then
+ echo "warning: FZF_CTRL_R_COMMAND is set to a custom command, but custom commands are not yet supported for CTRL-R" >&2
+ fi
+ bind -m emacs-standard -x '"\C-r": __fzf_history__'
+ bind -m vi-command -x '"\C-r": __fzf_history__'
+ bind -m vi-insert -x '"\C-r": __fzf_history__'
+ fi
+ fi
+
+ # ALT-C - cd into the selected directory
+ if [[ ${FZF_ALT_C_COMMAND-x} != "" ]]; then
+ bind -m emacs-standard '"\ec": " \C-b\C-k \C-u`__fzf_cd__`\e\C-e\er\C-m\C-y\C-h\e \C-y\ey\C-x\C-x\C-d\C-y\ey\C-_"'
+ bind -m vi-command '"\ec": "\C-z\ec\C-z"'
+ bind -m vi-insert '"\ec": "\C-z\ec\C-z"'
+ fi
+ #----END shfmt
+
+fi
+### end: key-bindings.bash ###
+### completion.bash ###
+# ____ ____
+# / __/___ / __/
+# / /_/_ / / /_
+# / __/ / /_/ __/
+# /_/ /___/_/ completion.bash
+#
+# - $FZF_TMUX (default: 0)
+# - $FZF_TMUX_OPTS (default: empty)
+# - $FZF_COMPLETION_TRIGGER (default: '**')
+# - $FZF_COMPLETION_OPTS (default: empty)
+# - $FZF_COMPLETION_PATH_OPTS (default: empty)
+# - $FZF_COMPLETION_DIR_OPTS (default: empty)
+
+if [[ $- =~ i ]]; then
+
+
+ # To use custom commands instead of find, override _fzf_compgen_{path,dir}
+ #
+ # _fzf_compgen_path() {
+ # echo "$1"
+ # command find -L "$1" \
+ # -name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
+ # -a -not -path "$1" -print 2> /dev/null | command sed 's@^\./@@'
+ # }
+ #
+ # _fzf_compgen_dir() {
+ # command find -L "$1" \
+ # -name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
+ # -a -not -path "$1" -print 2> /dev/null | command sed 's@^\./@@'
+ # }
+
+ ###########################################################
+
+ #----BEGIN shfmt
+ #----BEGIN INCLUDE common.sh
+ # NOTE: Do not directly edit this section, which is copied from "common.sh".
+ # To modify it, one can edit "common.sh" and run "./update.sh" to apply
+ # the changes. See code comments in "common.sh" for the implementation details.
+
+ __fzf_defaults() {
+ printf '%s\n' "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
+ command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
+ printf '%s\n' "${FZF_DEFAULT_OPTS-} $2"
+ }
+
+ __fzf_exec_awk() {
+ if [[ -z ${__fzf_awk-} ]]; then
+ __fzf_awk=awk
+ if [[ $OSTYPE == solaris* && -x /usr/xpg4/bin/awk ]]; then
+ __fzf_awk=/usr/xpg4/bin/awk
+ elif command -v mawk > /dev/null 2>&1; then
+ local n x y z d
+ IFS=' .' read -r n x y z d <<< $(command mawk -W version 2> /dev/null)
+ [[ $n == mawk ]] && ((d >= 20230302 && (x * 1000 + y) * 1000 + z >= 1003004)) && __fzf_awk=mawk
+ fi
+ fi
+ LC_ALL=C exec "$__fzf_awk" "$@"
+ }
+ #----END INCLUDE
+
+ __fzf_comprun() {
+ if [[ "$(type -t _fzf_comprun 2>&1)" == function ]]; then
+ _fzf_comprun "$@"
+ elif [[ -n ${TMUX_PANE-} ]] && { [[ ${FZF_TMUX:-0} != 0 ]] || [[ -n ${FZF_TMUX_OPTS-} ]]; }; then
+ shift
+ fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- "$@"
+ else
+ shift
+ fzf "$@"
+ fi
+ }
+
+ __fzf_orig_completion() {
+ local l comp f cmd
+ while read -r l; do
+ if [[ $l =~ ^(.*\ -F)\ *([^ ]*).*\ ([^ ]*)$ ]]; then
+ comp="${BASH_REMATCH[1]}"
+ f="${BASH_REMATCH[2]}"
+ cmd="${BASH_REMATCH[3]}"
+ [[ $f == _fzf_* ]] && continue
+ printf -v "_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}" "%s" "${comp} %s ${cmd} #${f}"
+ if [[ $l == *" -o nospace "* ]] && [[ ${__fzf_nospace_commands-} != *" $cmd "* ]]; then
+ __fzf_nospace_commands="${__fzf_nospace_commands-} $cmd "
+ fi
+ fi
+ done
+ }
+
+ # @param $1 cmd - Command name for which the original completion is searched
+ # @var[out] REPLY - Original function name is returned
+ __fzf_orig_completion_get_orig_func() {
+ local cmd orig_var orig
+ cmd=$1
+ orig_var="_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}"
+ orig="${!orig_var-}"
+ REPLY="${orig##*#}"
+ [[ $REPLY ]] && type "$REPLY" &> /dev/null
+ }
+
+ # @param $1 cmd - Command name for which the original completion is searched
+ # @param $2 func - Fzf's completion function to replace the original function
+ # @var[out] REPLY - Completion setting is returned as a string to "eval"
+ __fzf_orig_completion_instantiate() {
+ local cmd func orig_var orig
+ cmd=$1
+ func=$2
+ orig_var="_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}"
+ orig="${!orig_var-}"
+ orig="${orig%#*}"
+ [[ $orig == *' %s '* ]] || return 1
+ printf -v REPLY "$orig" "$func"
+ }
+
+ _fzf_opts_completion() {
+ local cur prev opts
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD - 1]}"
+ opts="
+ +c --no-color
+ +i --no-ignore-case
+ +s --no-sort
+ +x --no-extended
+ --ansi
+ --bash
+ --bind
+ --border
+ --border-label
+ --border-label-pos
+ --color
+ --cycle
+ --disabled
+ --ellipsis
+ --expect
+ --filepath-word
+ --fish
+ --header
+ --header-first
+ --header-lines
+ --height
+ --highlight-line
+ --history
+ --history-size
+ --hscroll-off
+ --info
+ --jump-labels
+ --keep-right
+ --layout
+ --listen
+ --listen-unsafe
+ --literal
+ --man
+ --margin
+ --marker
+ --min-height
+ --no-bold
+ --no-clear
+ --no-hscroll
+ --no-mouse
+ --no-scrollbar
+ --no-separator
+ --no-unicode
+ --padding
+ --pointer
+ --preview
+ --preview-label
+ --preview-label-pos
+ --preview-window
+ --print-query
+ --print0
+ --prompt
+ --read0
+ --reverse
+ --scheme
+ --scroll-off
+ --separator
+ --sync
+ --tabstop
+ --tac
+ --tiebreak
+ --tmux
+ --track
+ --version
+ --with-nth
+ --with-shell
+ --wrap
+ --zsh
+ -0 --exit-0
+ -1 --select-1
+ -d --delimiter
+ -e --exact
+ -f --filter
+ -h --help
+ -i --ignore-case
+ -m --multi
+ -n --nth
+ -q --query
+ --"
+
+ case "${prev}" in
+ --scheme)
+ COMPREPLY=($(compgen -W "default path history" -- "$cur"))
+ return 0
+ ;;
+ --tiebreak)
+ COMPREPLY=($(compgen -W "length chunk begin end index" -- "$cur"))
+ return 0
+ ;;
+ --color)
+ COMPREPLY=($(compgen -W "dark light 16 bw no" -- "$cur"))
+ return 0
+ ;;
+ --layout)
+ COMPREPLY=($(compgen -W "default reverse reverse-list" -- "$cur"))
+ return 0
+ ;;
+ --info)
+ COMPREPLY=($(compgen -W "default right hidden inline inline-right" -- "$cur"))
+ return 0
+ ;;
+ --preview-window)
+ COMPREPLY=($(compgen -W "
+ default
+ hidden
+ nohidden
+ wrap
+ nowrap
+ cycle
+ nocycle
+ up top
+ down bottom
+ left
+ right
+ rounded border border-rounded
+ sharp border-sharp
+ border-bold
+ border-block
+ border-thinblock
+ border-double
+ noborder border-none
+ border-horizontal
+ border-vertical
+ border-up border-top
+ border-down border-bottom
+ border-left
+ border-right
+ follow
+ nofollow" -- "$cur"))
+ return 0
+ ;;
+ --border)
+ COMPREPLY=($(compgen -W "rounded sharp bold block thinblock double horizontal vertical top bottom left right none" -- "$cur"))
+ return 0
+ ;;
+ --border-label-pos | --preview-label-pos)
+ COMPREPLY=($(compgen -W "center bottom top" -- "$cur"))
+ return 0
+ ;;
+ esac
+
+ if [[ $cur =~ ^-|\+ ]]; then
+ COMPREPLY=($(compgen -W "${opts}" -- "$cur"))
+ return 0
+ fi
+
+ return 0
+ }
+
+ _fzf_handle_dynamic_completion() {
+ local cmd ret REPLY orig_cmd orig_complete
+ cmd="$1"
+ shift
+ orig_cmd="$1"
+ if __fzf_orig_completion_get_orig_func "$cmd"; then
+ "$REPLY" "$@"
+ elif [[ -n ${_fzf_completion_loader-} ]]; then
+ orig_complete=$(complete -p "$orig_cmd" 2> /dev/null)
+ $_fzf_completion_loader "$@"
+ ret=$?
+ # _completion_loader may not have updated completion for the command
+ if [[ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]]; then
+ __fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null)
+ __fzf_orig_completion_get_orig_func "$cmd" || ret=1
+
+ # Update orig_complete by _fzf_orig_completion entry
+ [[ $orig_complete =~ ' -F '(_fzf_[^ ]+)' ' ]] &&
+ __fzf_orig_completion_instantiate "$cmd" "${BASH_REMATCH[1]}" &&
+ orig_complete=$REPLY
+
+ if [[ ${__fzf_nospace_commands-} == *" $orig_cmd "* ]]; then
+ eval "${orig_complete/ -F / -o nospace -F }"
+ else
+ eval "$orig_complete"
+ fi
+ fi
+ [[ $ret -eq 0 ]] && return 124
+ return $ret
+ fi
+ }
+
+ __fzf_generic_path_completion() {
+ local cur base dir leftover matches trigger cmd
+ cmd="${COMP_WORDS[0]}"
+ if [[ $cmd == \\* ]]; then
+ cmd="${cmd:1}"
+ fi
+ COMPREPLY=()
+ trigger=${FZF_COMPLETION_TRIGGER-'**'}
+ [[ $COMP_CWORD -ge 0 ]] && cur="${COMP_WORDS[COMP_CWORD]}"
+ if [[ $cur == *"$trigger" ]] && [[ $cur != *'$('* ]] && [[ $cur != *':='* ]] && [[ $cur != *'`'* ]]; then
+ base=${cur:0:${#cur}-${#trigger}}
+ eval "base=$base" 2> /dev/null || return
+
+ dir=
+ [[ $base == *"/"* ]] && dir="$base"
+ while true; do
+ if [[ -z $dir ]] || [[ -d $dir ]]; then
+ leftover=${base/#"$dir"/}
+ leftover=${leftover/#\//}
+ [[ -z $dir ]] && dir='.'
+ [[ $dir != "/" ]] && dir="${dir/%\//}"
+ matches=$(
+ export FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --scheme=path" "${FZF_COMPLETION_OPTS-} $2")
+ unset FZF_DEFAULT_COMMAND FZF_DEFAULT_OPTS_FILE
+ if declare -F "$1" > /dev/null; then
+ eval "$1 $(printf %q "$dir")" | __fzf_comprun "$4" -q "$leftover"
+ else
+ if [[ $1 =~ dir ]]; then
+ walker=dir,follow
+ eval "rest=(${FZF_COMPLETION_DIR_OPTS-})"
+ else
+ walker=file,dir,follow,hidden
+ eval "rest=(${FZF_COMPLETION_PATH_OPTS-})"
+ fi
+ __fzf_comprun "$4" -q "$leftover" --walker "$walker" --walker-root="$dir" "${rest[@]}"
+ fi | while read -r item; do
+ printf "%q " "${item%$3}$3"
+ done
+ )
+ matches=${matches% }
+ [[ -z $3 ]] && [[ ${__fzf_nospace_commands-} == *" ${COMP_WORDS[0]} "* ]] && matches="$matches "
+ if [[ -n $matches ]]; then
+ COMPREPLY=("$matches")
+ else
+ COMPREPLY=("$cur")
+ fi
+ # To redraw line after fzf closes (printf '\e[5n')
+ bind '"\e[0n": redraw-current-line' 2> /dev/null
+ printf '\e[5n'
+ return 0
+ fi
+ dir=$(command dirname "$dir")
+ [[ $dir =~ /$ ]] || dir="$dir"/
+ done
+ else
+ shift
+ shift
+ shift
+ _fzf_handle_dynamic_completion "$cmd" "$@"
+ fi
+ }
+
+ _fzf_complete() {
+ # Split arguments around --
+ local args rest str_arg i sep
+ args=("$@")
+ sep=
+ for i in "${!args[@]}"; do
+ if [[ ${args[$i]} == -- ]]; then
+ sep=$i
+ break
+ fi
+ done
+ if [[ -n $sep ]]; then
+ str_arg=
+ rest=("${args[@]:$((sep + 1)):${#args[@]}}")
+ args=("${args[@]:0:sep}")
+ else
+ str_arg=$1
+ args=()
+ shift
+ rest=("$@")
+ fi
+
+ local cur selected trigger cmd post
+ post="$(caller 0 | __fzf_exec_awk '{print $2}')_post"
+ type -t "$post" > /dev/null 2>&1 || post='command cat'
+
+ trigger=${FZF_COMPLETION_TRIGGER-'**'}
+ cmd="${COMP_WORDS[0]}"
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ if [[ $cur == *"$trigger" ]] && [[ $cur != *'$('* ]] && [[ $cur != *':='* ]] && [[ $cur != *'`'* ]]; then
+ cur=${cur:0:${#cur}-${#trigger}}
+
+ selected=$(
+ FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse" "${FZF_COMPLETION_OPTS-} $str_arg") \
+ FZF_DEFAULT_OPTS_FILE='' \
+ __fzf_comprun "${rest[0]}" "${args[@]}" -q "$cur" | eval "$post" | command tr '\n' ' '
+ )
+ selected=${selected% } # Strip trailing space not to repeat "-o nospace"
+ if [[ -n $selected ]]; then
+ COMPREPLY=("$selected")
+ else
+ COMPREPLY=("$cur")
+ fi
+ bind '"\e[0n": redraw-current-line' 2> /dev/null
+ printf '\e[5n'
+ return 0
+ else
+ _fzf_handle_dynamic_completion "$cmd" "${rest[@]}"
+ fi
+ }
+
+ _fzf_path_completion() {
+ __fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@"
+ }
+
+ # Deprecated. No file only completion.
+ _fzf_file_completion() {
+ _fzf_path_completion "$@"
+ }
+
+ _fzf_dir_completion() {
+ __fzf_generic_path_completion _fzf_compgen_dir "" "/" "$@"
+ }
+
+ _fzf_complete_kill() {
+ _fzf_proc_completion "$@"
+ }
+
+ _fzf_proc_completion() {
+ local transformer
+ transformer='
+ if [[ $FZF_KEY =~ ctrl|alt|shift ]] && [[ -n $FZF_NTH ]]; then
+ nths=( ${FZF_NTH//,/ } )
+ new_nths=()
+ found=0
+ for nth in ${nths[@]}; do
+ if [[ $nth = $FZF_CLICK_HEADER_NTH ]]; then
+ found=1
+ else
+ new_nths+=($nth)
+ fi
+ done
+ [[ $found = 0 ]] && new_nths+=($FZF_CLICK_HEADER_NTH)
+ new_nths=${new_nths[*]}
+ new_nths=${new_nths// /,}
+ echo "change-nth($new_nths)+change-prompt($new_nths> )"
+ else
+ if [[ $FZF_NTH = $FZF_CLICK_HEADER_NTH ]]; then
+ echo "change-nth()+change-prompt(> )"
+ else
+ echo "change-nth($FZF_CLICK_HEADER_NTH)+change-prompt($FZF_CLICK_HEADER_WORD> )"
+ fi
+ fi
+ '
+ _fzf_complete -m --header-lines=1 --no-preview --wrap --color fg:dim,nth:regular \
+ --bind "click-header:transform:$transformer" -- "$@" < <(
+ command ps -eo user,pid,ppid,start,time,command 2> /dev/null ||
+ command ps -eo user,pid,ppid,time,args 2> /dev/null || # For BusyBox
+ command ps --everyone --full --windows # For cygwin
+ )
+ }
+
+ _fzf_proc_completion_post() {
+ __fzf_exec_awk '{print $2}'
+ }
+
+ # To use custom hostname lists, override __fzf_list_hosts.
+ # The function is expected to print hostnames, one per line as well as in the
+ # desired sorting and with any duplicates removed, to standard output.
+ #
+ # e.g.
+ # # Use bash-completions’s _known_hosts_real() for getting the list of hosts
+ # __fzf_list_hosts() {
+ # # Set the local attribute for any non-local variable that is set by _known_hosts_real()
+ # local COMPREPLY=()
+ # _known_hosts_real ''
+ # printf '%s\n' "${COMPREPLY[@]}" | command sort -u --version-sort
+ # }
+ if ! declare -F __fzf_list_hosts > /dev/null; then
+ __fzf_list_hosts() {
+ command sort -u \
+ <(
+ # Note: To make the pathname expansion of "~/.ssh/config.d/*" work
+ # properly, we need to adjust the related shell options. We need to
+ # unset "set -f" and "GLOBIGNORE", which disable the pathname expansion
+ # totally or partially. We need to unset "dotglob" and "nocaseglob" to
+ # avoid matching unwanted files. We need to unset "failglob" to avoid
+ # outputting the error messages to the terminal when no matching is
+ # found. We need to set "nullglob" to avoid attempting to read the
+ # literal filename '~/.ssh/config.d/*' when no matching is found.
+ set +f
+ GLOBIGNORE=
+ shopt -u dotglob nocaseglob failglob
+ shopt -s nullglob
+
+ __fzf_exec_awk '
+ # Note: mawk <= 1.3.3-20090705 does not support the POSIX brackets of
+ # the form [[:blank:]], and Ubuntu 18.04 LTS still uses this
+ # 16-year-old mawk unfortunately. We need to use [ \t] instead.
+ match(tolower($0), /^[ \t]*host(name)?[ \t]*[ \t=]/) {
+ $0 = substr($0, RLENGTH + 1) # Remove "Host(name)?=?"
+ sub(/#.*/, "")
+ for (i = 1; i <= NF; i++)
+ if ($i !~ /[*?%]/)
+ print $i
+ }
+ ' ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null
+ ) \
+ <(
+ __fzf_exec_awk -F ',' '
+ match($0, /^[][a-zA-Z0-9.,:-]+/) {
+ $0 = substr($0, 1, RLENGTH)
+ gsub(/[][]|:[^,]*/, "")
+ for (i = 1; i <= NF; i++)
+ print $i
+ }
+ ' ~/.ssh/known_hosts 2> /dev/null
+ ) \
+ <(
+ __fzf_exec_awk '
+ {
+ sub(/#.*/, "")
+ for (i = 2; i <= NF; i++)
+ if ($i != "0.0.0.0")
+ print $i
+ }
+ ' /etc/hosts 2> /dev/null
+ )
+ }
+ fi
+
+ _fzf_host_completion() {
+ _fzf_complete +m -- "$@" < <(__fzf_list_hosts)
+ }
+
+ # Values for $1 $2 $3 are described here
+ # https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html
+ # > the first argument ($1) is the name of the command whose arguments are being completed,
+ # > the second argument ($2) is the word being completed,
+ # > and the third argument ($3) is the word preceding the word being completed on the current command line.
+ _fzf_complete_ssh() {
+ case $3 in
+ -i | -F | -E)
+ _fzf_path_completion "$@"
+ ;;
+ *)
+ local user=
+ [[ $2 =~ '@' ]] && user="${2%%@*}@"
+ _fzf_complete +m -- "$@" < <(__fzf_list_hosts | __fzf_exec_awk -v user="$user" '{print user $0}')
+ ;;
+ esac
+ }
+
+ _fzf_var_completion() {
+ _fzf_complete -m -- "$@" < <(
+ declare -xp | command sed -En 's|^declare [^ ]+ ([^=]+).*|\1|p'
+ )
+ }
+
+ _fzf_alias_completion() {
+ _fzf_complete -m -- "$@" < <(
+ alias | command sed -En 's|^alias ([^=]+).*|\1|p'
+ )
+ }
+
+ # fzf options
+ complete -o default -F _fzf_opts_completion fzf
+ # fzf-tmux is a thin fzf wrapper that has only a few more options than fzf
+ # itself. As a quick improvement we take fzf's completion. Adding the few extra
+ # fzf-tmux specific options (like `-w WIDTH`) are left as a future patch.
+ complete -o default -F _fzf_opts_completion fzf-tmux
+
+ # Default path completion
+ __fzf_default_completion() {
+ __fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@"
+
+ # Dynamic completion loader has updated the completion for the command
+ if [[ $? -eq 124 ]]; then
+ # We trigger _fzf_setup_completion so that fuzzy completion for the command
+ # still works. However, loader can update the completion for multiple
+ # commands at once, and fuzzy completion will no longer work for those
+ # other commands. e.g. pytest -> py.test, pytest-2, pytest-3, etc
+ _fzf_setup_completion path "$1"
+ return 124
+ fi
+ }
+
+ # Set fuzzy path completion as the default completion for all commands.
+ # We can't set up default completion,
+ # 1. if it's already set up by another script
+ # 2. or if the current version of bash doesn't support -D option
+ complete | command grep -q __fzf_default_completion ||
+ complete | command grep -- '-D$' | command grep -qv _comp_complete_load ||
+ complete -D -F __fzf_default_completion -o default -o bashdefault 2> /dev/null
+
+ d_cmds="${FZF_COMPLETION_DIR_COMMANDS-cd pushd rmdir}"
+
+ # NOTE: $FZF_COMPLETION_PATH_COMMANDS and $FZF_COMPLETION_VAR_COMMANDS are
+ # undocumented and subject to change in the future.
+ #
+ # NOTE: Although we have default completion, we still need to set up completion
+ # for each command in case they already have completion set up by another script.
+ a_cmds="${FZF_COMPLETION_PATH_COMMANDS-"
+ awk bat cat code diff diff3
+ emacs emacsclient ex file ftp g++ gcc gvim head hg hx java
+ javac ld less more mvim nvim patch perl python ruby
+ sed sftp sort source tail tee uniq vi view vim wc xdg-open
+ basename bunzip2 bzip2 chmod chown curl cp dirname du
+ find git grep gunzip gzip hg jar
+ ln ls mv open rm rsync scp
+ svn tar unzip zip"}"
+ v_cmds="${FZF_COMPLETION_VAR_COMMANDS-export unset printenv}"
+
+ # Preserve existing completion
+ # iank: added ||: at the end, exit is nonzero due to some commands not having a completion spec.
+ __fzf_orig_completion < <(complete -p $d_cmds $a_cmds $v_cmds unalias kill ssh 2> /dev/null ||:)
+
+ if type _comp_load > /dev/null 2>&1; then
+ # _comp_load was added in bash-completion 2.12 to replace _completion_loader.
+ # We use it without -D option so that it does not use _comp_complete_minimal as the fallback.
+ _fzf_completion_loader=_comp_load
+ elif type __load_completion > /dev/null 2>&1; then
+ # In bash-completion 2.11, _completion_loader internally calls __load_completion
+ # and if it returns a non-zero status, it sets the default 'minimal' completion.
+ _fzf_completion_loader=__load_completion
+ elif type _completion_loader > /dev/null 2>&1; then
+ _fzf_completion_loader=_completion_loader
+ fi
+
+ __fzf_defc() {
+ local cmd func opts REPLY
+ cmd="$1"
+ func="$2"
+ opts="$3"
+ if __fzf_orig_completion_instantiate "$cmd" "$func"; then
+ eval "$REPLY"
+ else
+ eval "complete -F \"$func\" $opts \"$cmd\""
+ fi
+ }
+
+ # Anything
+ for cmd in $a_cmds; do
+ __fzf_defc "$cmd" _fzf_path_completion "-o default -o bashdefault"
+ done
+
+ # Directory
+ for cmd in $d_cmds; do
+ __fzf_defc "$cmd" _fzf_dir_completion "-o bashdefault -o nospace -o dirnames"
+ done
+
+ # Variables
+ for cmd in $v_cmds; do
+ __fzf_defc "$cmd" _fzf_var_completion "-o default -o nospace -v"
+ done
+
+ # Aliases
+ __fzf_defc unalias _fzf_alias_completion "-a"
+
+ # Processes
+ __fzf_defc kill _fzf_proc_completion "-o default -o bashdefault"
+
+ # ssh
+ __fzf_defc ssh _fzf_complete_ssh "-o default -o bashdefault"
+
+ unset cmd d_cmds a_cmds v_cmds
+
+ _fzf_setup_completion() {
+ local kind fn cmd
+ kind=$1
+ fn=_fzf_${1}_completion
+ if [[ $# -lt 2 ]] || ! type -t "$fn" > /dev/null; then
+ echo "usage: ${FUNCNAME[0]} path|dir|var|alias|host|proc COMMANDS..."
+ return 1
+ fi
+ shift
+ __fzf_orig_completion < <(complete -p "$@" 2> /dev/null)
+ for cmd in "$@"; do
+ case "$kind" in
+ dir) __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
+ var) __fzf_defc "$cmd" "$fn" "-o default -o nospace -v" ;;
+ alias) __fzf_defc "$cmd" "$fn" "-a" ;;
+ *) __fzf_defc "$cmd" "$fn" "-o default -o bashdefault" ;;
+ esac
+ done
+ }
+ #----END shfmt
+
+fi
+### end: completion.bash ###
+
+
+# ensure no bad programs appending to this file will have an affect
+return 0
# https://docs.nextcloud.com/server/latest/admin_manual/maintenance/restore.html
if $restore; then
set -x
- for ncdir in /var/www/ncexpertpath /var/www/ncninja; do
+ for ncdir in /var/www/ncninja; do
ncbase=${ncdir##*/}
ssh root@$host sudo -u www-data php $ncdir/occ -q maintenance:mode --on ||: # might not be running
rsync -ravhi --numeric-ids /p/bkbackup/$ncbase/ root@$host:$ncdir || ret=$?
ret=0
if [[ $HOSTNAME == "$MAIL_HOST" ]]; then
mkdir -p /p/bkbackup
- for ncdir in /var/www/ncexpertpath /var/www/ncninja; do
+ for ncdir in /var/www/ncninja; do
ncbase=${ncdir##*/}
mkdir -p /p/bkbackup/$ncbase
ssh root@$host sudo -u www-data php $ncdir/occ -q maintenance:mode --on
btrbk-run [OPTIONS] [run|resume|archive]
usually -t TARGET_HOST or -s SOURCE_HOST
+Options:
+
+-2|-3 Config suffix, for the rare case we want to run multiple instances at the same time.
+
+-a Use all known mountpoints.
+
+-c Config creation only.
+
+-e Quit early, just btrbk, no extra remounting etc.
+
+-f Avoids some default behaviors:
+ - exit if we can't ssh to 1 or more hosts
+ - still set default hosts despite MAIL_HOST status
+ - negates -x.
+
+--fast Skip various checks. when we run twice in a row for
+ switch mail-host, no need to repeat the same checks again.
+
+-k Aka kd_spread. Run in resume mode to spread recent backup to other home lan hosts.
+ This implies resume and -p because it is just meant to make
+ other hosts have the same snapshots, not do any expiry or new
+ backups.
+
+-l RATE_LIMIT Bytes per second unless it has a suffix of k/m/g.
+
+-m MOUNTPOINTS Comma separated mountpoints to backup. This has defaults, see code logic.
+
+-p Preserve existing snapshots and backups
+
+--pull-reexec Internal option for rerunning under newer SOURCE_HOST version.
+
+
+-q Quiet.
+
+-s SOURCE_HOST Source host to receive a backup from
+
+-t TARGET_HOSTS Target hosts to send to. empty is valid for just doing local
+ snapshot. we have default hosts we will populate.
+
+-v Verbose
+
+-x Exit if we have unlocked xscreensaver, to avoid interrupting machine in active use.
+ -f turns this off.
+
+-h|--help Print usage.
+
EOF
echo "top of script file:"
sed -n '/^[# ]*begin command line/,/^[# ]*end command line/{p;b};q' "$0"
write-config() {
local q_mp=false
local -a tmp_mps
+ local mp
+ snap_list_glob=
cat >/etc/btrbk$conf_suf.conf <<EOF
ssh_identity /q/root/h
fi
# make /q be last.
- mp_count=${#mountpoints[@]}
- for (( i=0; i < mp_count - 1 ; i++ )); do
- if [[ ${mountpoints[i]} == /q ]]; then
+ for mp in "${mountpoints[@]}"; do
+ if [[ $mp == /q ]]; then
q_mp=true
else
- tmp_mps+=(${mountpoints[i]})
+ tmp_mps+=($mp)
fi
done
if $q_mp; then
get-orphan-tg-snaps() {
- local mp_to_snap_regex snap
+ local mp_to_snap_regex snap mp mp_tg_snap
+ local -i i
local -a mp_orphan_tg_snaps mp_tg_snaps
+ orphan_tg_snaps=()
+
## sanity checking
for (( i=0; i < ${#tg_snaps[@]}; i++ )); do
if [[ ! ${tg_snaps[$i]} =~ $good_path_regex ]]; then
fi
done
+ # debug
+ if $verbose; then
+ echo "source_snaps: ${!source_snaps[@]}"
+ echo "tg_snaps: ${tg_snaps[@]}"
+ echo "mountpoints: ${mountpoints[@]}"
+ echo "snap_list_glob: $snap_list_glob"
+ fi
+
# note: we do each mountpoint separately just so we can better sanity
# check that we aren't incorrectly classifying all target snaps as
done
for mp_tg_snap in "${mp_tg_snaps[@]}"; do
if [[ ! ${source_snaps[$mp_tg_snap]} ]]; then
- orphan_tg_snaps+=("$tg_snap")
- mp_orphan_tg_snaps+=("$tg_snap")
+ orphan_tg_snaps+=("$mp_tg_snap")
+ mp_orphan_tg_snaps+=("$mp_tg_snap")
fi
## sanity checking
# for the rare case we want to run multiple instances at the same time
-2) conf_suf=2 ;;
-3) conf_suf=3 ;;
- -a)
- # all moiuntpoints
+ -a) # all
mountpoints=(/a /o /q)
;;
- # only creates the config file, does not run btrbk
-c) conf_only=true ;;
--check-installed)
check_installed=true
;;
- # quit early, just btrbk, no extra remounting etc.
- -e) early=true ;;
- # avoids some default behaviors:
- # - exit if we can't ssh to 1 or more hosts
- # - still set default hosts despite MAIL_HOST status
- # - negates -x.
+ -e) early=true ;; # quit early
-f) force=true ;;
- # skip various checks. when we run twice in a row for
- # switch mail-host, no need to repeat the same checks again.
--fast) fast=true ;;
-i) incremental_strict=true ;;
- # note this implies resume and -p because it is just meant to make
- # other hosts have the same snapshots, not do any expiry or new
- # backups.
-k) kd_spread=true ;;
- # bytes per second, suffix k m g
-l) rate_limit=$2; shift ;;
- # Comma separated mountpoints to backup. This has defaults set below.
-m) IFS=, mountpoints=($2); unset IFS; shift ;;
-n) dry_run=true ;;
- # preserve existing snapshots and backups
-p) preserve_arg=-p ;;
- # internal option for rerunning under newer SOURCE_HOST version.
--pull-reexec) pull_reexec=true;;
# quiet
-q) verbose=false; verbose_arg=; progress_arg= ;;
- # source host to receive a backup from
-s)
source=$2
bbksource=$source
fi
shift
;;
- # target hosts to send to. empty is valid for just doing local
- # snapshot. we have default hosts we will populate.
-t) IFS=, targets=($2); unset IFS; shift ;;
# verbose.
-v)
verbose=true; verbose_arg="-l trace"
;;
- # exit if we have unlocked xscreensaver, to avoid interrupting machine in active use.
- # -f turns this off.
-x) xlock=true ;;
-h|--help) usage ;;
--) shift; break ;;
## https://github.com/i3/i3/issues/2971
window=$(xdotool getwindowfocus)
+name=$(xdotool getwindowname $window)
+
# this brings in variables WIDTH and HEIGHT
eval "$(xdotool getwindowgeometry --shell $window)"
if (( HEIGHT > 100 )); then
- TX=$(( WIDTH / 2))
- TY=$(( HEIGHT / 2))
+
+ if [[ $name == i2x\ * ]]; then
+ TX=80
+ TY=0
+ else
+ TX=$(( WIDTH / 2))
+ TY=$(( HEIGHT / 2))
+ fi
xdotool mousemove -window $window $TX $TY
# iank, original says "Check for height of 100 assumes that anything
run_as_nonroot=true
if $run_as_nonroot; then
- # settings that go away when exim gets upgraded. obviously the best
- # way to do this would be to modify the exim package itself, but this
- # is easier.
- caps=$(getcap /usr/sbin/exim4)
- if [[ ! $caps ]]; then
- echo "$0: setting capabilities, user and setuid/gid on /usr/sbin/exim4"
- chown Debian-exim:Debian-exim /usr/sbin/exim4
- chmod g+s,u+s /usr/sbin/exim4
- setcap CAP_NET_BIND_SERVICE+ei /usr/sbin/exim4
+ # settings that go away when exim gets upgraded. obviously the best
+ # way to do this would be to modify the exim package itself, but this
+ # is easier.
+ caps=$(getcap /usr/sbin/exim4)
+ if [[ ! $caps ]]; then
+ echo "$0: setting capabilities, user and setuid/gid on /usr/sbin/exim4"
+ chown Debian-exim:Debian-exim /usr/sbin/exim4
+ chmod g+s,u+s /usr/sbin/exim4
+ setcap CAP_NET_BIND_SERVICE+ei /usr/sbin/exim4
+ fi
fi
-
-
done
file "/var/lib/bind/db.zroe.org.signed";
};
-zone "expertpathologyreview.com" {
-type master;
-file "/var/lib/bind/db.expertpathologyreview.com.signed";
-};
-
zone "amnimal.ninja" {
type master;
file "/var/lib/bind/db.amnimal.ninja.signed";
local -a p_unexpected_spamd_results p_missing_dnswl p_last_usec
case $HOSTNAME in
bk)
- folders=(/m/md/{expertpathologyreview.com,amnimal.ninja}/testignore)
+ folders=(/m/md/{amnimal.ninja}/testignore)
froms=(ian@iankelling.org z@zroe.org testignore@je.b8.nz iank@gnu.org)
;;
je)
*)
folders=(/m/md/l/testignore)
# save some cpu cycles
- froms=(testignore@je.b8.nz testignore@expertpathologyreview.com testignore@amnimal.ninja ian@iankelling.org z@zroe.org)
+ froms=(testignore@je.b8.nz testignore@amnimal.ninja ian@iankelling.org z@zroe.org)
if ! $int; then
### begin rsyncing fencepost email ###
# We dont want to exit if rsync fails, that will get caught by
+
[global]
+ ### Display ###
+
+ # Which monitor should the notifications be displayed on.
monitor = 0
- follow = mouse
- geometry = "300x5-30+20"
+
+ # Display notification on focused monitor. Possible modes are:
+ # mouse: follow mouse pointer
+ # keyboard: follow window with keyboard focus
+ # none: don't follow anything
+ #
+ # "keyboard" needs a window manager that exports the
+ # _NET_ACTIVE_WINDOW property.
+ # This should be the case for almost all modern window managers.
+ #
+ # If this option is set to mouse or keyboard, the monitor option
+ # will be ignored.
+ follow = none
+
+ ### Geometry ###
+
+ # dynamic width from 0 to 300
+ # width = (0, 300)
+ # constant width of 300
+ width = 300
+
+ # The maximum height of a single notification, excluding the frame.
+ height = 300
+
+ # Position the notification in the top right corner
+ origin = top-right
+
+ # Offset from the origin
+ offset = 700x50
+
+ # Scale factor. It is auto-detected if value is 0.
+ scale = 0
+
+ # Maximum number of notification (0 means no limit)
+ notification_limit = 20
+
+ ### Progress bar ###
+
+ # Turn on the progess bar. It appears when a progress hint is passed with
+ # for example dunstify -h int:value:12
+ progress_bar = true
+
+ # Set the progress bar height. This includes the frame, so make sure
+ # it's at least twice as big as the frame width.
+ progress_bar_height = 10
+
+ # Set the frame width of the progress bar
+ progress_bar_frame_width = 1
+
+ # Set the minimum width for the progress bar
+ progress_bar_min_width = 150
+
+ # Set the maximum width for the progress bar
+ progress_bar_max_width = 300
+
+ # Corner radius for the progress bar. 0 disables rounded corners.
+ progress_bar_corner_radius = 0
+
+ # Corner radius for the icon image.
+ icon_corner_radius = 0
+
+ # Show how many messages are currently hidden (because of
+ # notification_limit).
indicate_hidden = yes
- shrink = no
+
+ # The transparency of the window. Range: [0; 100].
+ # This option will only work if a compositing window manager is
+ # present (e.g. xcompmgr, compiz, etc.). (X11 only)
transparency = 0
- notification_height = 0
+
+ # Draw a line of "separator_height" pixel height between two
+ # notifications.
+ # Set to 0 to disable.
+ # If gap_size is greater than 0, this setting will be ignored.
separator_height = 2
+
+ # Padding between text and separator.
padding = 8
+
+ # Horizontal padding.
horizontal_padding = 8
+
+ # Padding between text and icon.
+ text_icon_padding = 0
+
+ # Defines width in pixels of frame around the notification window.
+ # Set to 0 to disable.
frame_width = 3
+
+ # Defines color of the frame around the notification window.
frame_color = "#aaaaaa"
+
+ # Size of gap to display between notifications - requires a compositor.
+ # If value is greater than 0, separator_height will be ignored and a border
+ # of size frame_width will be drawn around each notification instead.
+ # Click events on gaps do not currently propagate to applications below.
+ gap_size = 0
+
+ # Define a color for the separator.
+ # possible values are:
+ # * auto: dunst tries to find a color fitting to the background;
+ # * foreground: use the same color as the foreground;
+ # * frame: use the same color as the frame;
+ # * anything else will be interpreted as a X color.
separator_color = frame
+
+ # Sort messages by urgency.
sort = yes
- idle_threshold = 120
+
+ # Don't remove messages, if the user is idle (no mouse or keyboard input)
+ # for longer than idle_threshold seconds.
+ # Set to 0 to disable.
+ # A client can set the 'transient' hint to bypass this. See the rules
+ # section for how to disable this if necessary
+ # idle_threshold = 120
+
+ ### Text ###
+
font = Monospace 8
+
+ # The spacing between lines. If the height is smaller than the
+ # font height, it will get raised to the font height.
line_height = 0
+
+ # Possible values are:
+ # full: Allow a small subset of html markup in notifications:
+ # <b>bold</b>
+ # <i>italic</i>
+ # <s>strikethrough</s>
+ # <u>underline</u>
+ #
+ # For a complete reference see
+ # <https://docs.gtk.org/Pango/pango_markup.html>.
+ #
+ # strip: This setting is provided for compatibility with some broken
+ # clients that send markup even though it's not enabled on the
+ # server. Dunst will try to strip the markup but the parsing is
+ # simplistic so using this option outside of matching rules for
+ # specific applications *IS GREATLY DISCOURAGED*.
+ #
+ # no: Disable markup parsing, incoming notifications will be treated as
+ # plain text. Dunst will not advertise that it has the body-markup
+ # capability if this is set as a global setting.
+ #
+ # It's important to note that markup inside the format option will be parsed
+ # regardless of what this is set to.
markup = full
+
+ # The format of the message. Possible variables are:
+ # %a appname
+ # %s summary
+ # %b body
+ # %i iconname (including its path)
+ # %I iconname (without its path)
+ # %p progress value if set ([ 0%] to [100%]) or nothing
+ # %n progress value if set without any extra characters
+ # %% Literal %
+ # Markup is allowed
format = "<b>%s</b>\n%b"
+
+ # Alignment of message text.
+ # Possible values are "left", "center" and "right".
alignment = left
+
+ # Vertical alignment of message text and icon.
+ # Possible values are "top", "center" and "bottom".
vertical_alignment = center
+
+ # Show age of message if message is older than show_age_threshold
+ # seconds.
+ # Set to -1 to disable.
show_age_threshold = 60
- word_wrap = yes
+
+ # Specify where to make an ellipsis in long lines.
+ # Possible values are "start", "middle" and "end".
ellipsize = middle
+
+ # Ignore newlines '\n' in notifications.
ignore_newline = no
+
+ # Stack together notifications with the same content
stack_duplicates = true
+
+ # Hide the count of stacked notifications with the same content
hide_duplicate_count = false
+
+ # Display indicators for URLs (U) and actions (A).
show_indicators = yes
+
+ ### Icons ###
+
+ # Recursive icon lookup. You can set a single theme, instead of having to
+ # define all lookup paths.
+ enable_recursive_icon_lookup = true
+
+ # Set icon theme (only used for recursive icon lookup)
+ icon_theme = Adwaita
+ # You can also set multiple icon themes, with the leftmost one being used first.
+ # icon_theme = "Adwaita, breeze"
+
+ # Align icons left/right/top/off
icon_position = left
- min_icon_size = 0
- max_icon_size = 32
+
+ # Scale small icons up to this size, set to 0 to disable. Helpful
+ # for e.g. small files or high-dpi screens. In case of conflict,
+ # max_icon_size takes precedence over this.
+ min_icon_size = 32
+
+ # Scale larger icons down to this size, set to 0 to disable
+ max_icon_size = 128
+
+ # Paths to default icons (only neccesary when not using recursive icon lookup)
icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
+
+ ### History ###
+
+ # Should a notification popped up from history be sticky or timeout
+ # as if it would normally do.
sticky_history = yes
+
+ # Maximum amount of notifications kept in history
history_length = 20
+
+ ### Misc/Advanced ###
+
+ # dmenu path.
dmenu = /usr/bin/dmenu -p dunst:
- browser = /usr/bin/sensible-browser
+
+ # Browser for opening urls in context menu.
+ browser = /usr/bin/xdg-open
+
+ # Always run rule-defined scripts, even if the notification is suppressed
always_run_script = true
+
+ # Define the title of the windows spawned by dunst
title = Dunst
+
+ # Define the class of the windows spawned by dunst
class = Dunst
- startup_notification = false
- verbosity = mesg
+
+ # Define the corner radius of the notification window
+ # in pixel size. If the radius is 0, you have no rounded
+ # corners.
+ # The radius will be automatically lowered if it exceeds half of the
+ # notification height to avoid clipping text and/or icons.
corner_radius = 0
+
+ # Ignore the dbus closeNotification message.
+ # Useful to enforce the timeout set by dunst configuration. Without this
+ # parameter, an application may close the notification sent before the
+ # user defined timeout.
ignore_dbusclose = false
+
+ ### Wayland ###
+ # These settings are Wayland-specific. They have no effect when using X11
+
+ # Uncomment this if you want to let notications appear under fullscreen
+ # applications (default: overlay)
+ # layer = top
+
+ # Set this to true to use X11 output on Wayland.
+ force_xwayland = false
+
+ ### Legacy
+
+ # Use the Xinerama extension instead of RandR for multi-monitor support.
+ # This setting is provided for compatibility with older nVidia drivers that
+ # do not support RandR and using it on systems that support RandR is highly
+ # discouraged.
+ #
+ # By enabling this setting dunst will not be able to detect when a monitor
+ # is connected or disconnected which might break follow mode if the screen
+ # layout changes.
force_xinerama = false
+
+ ### mouse
+
+ # Defines list of actions for each mouse event
+ # Possible values are:
+ # * none: Don't do anything.
+ # * do_action: Invoke the action determined by the action_name rule. If there is no
+ # such action, open the context menu.
+ # * open_url: If the notification has exactly one url, open it. If there are multiple
+ # ones, open the context menu.
+ # * close_current: Close current notification.
+ # * close_all: Close all notifications.
+ # * context: Open context menu for the notification.
+ # * context_all: Open context menu for all notifications.
+ # These values can be strung together for each mouse event, and
+ # will be executed in sequence.
mouse_left_click = close_current
mouse_middle_click = do_action, close_current
mouse_right_click = close_all
+
+# Experimental features that may or may not work correctly. Do not expect them
+# to have a consistent behaviour across releases.
[experimental]
+ # Calculate the dpi to use on a per-monitor basis.
+ # If this setting is enabled the Xft.dpi value will be ignored and instead
+ # dunst will attempt to calculate an appropriate dpi value for each monitor
+ # using the resolution and physical size. This might be useful in setups
+ # where there are multiple screens with very different dpi values.
per_monitor_dpi = false
-[shortcuts]
- close = ctrl+space
- close_all = ctrl+shift+space
- history = ctrl+grave
- context = ctrl+shift+period
+
+
[urgency_low]
+ # IMPORTANT: colors have to be defined in quotation marks.
+ # Otherwise the "#" and following would be interpreted as a comment.
background = "#222222"
foreground = "#888888"
timeout = 10
+ # Icon for notifications with low urgency, uncomment to enable
+ #default_icon = /path/to/icon
+
[urgency_normal]
background = "#285577"
foreground = "#ffffff"
timeout = 10
+ # Icon for notifications with normal urgency, uncomment to enable
+ #default_icon = /path/to/icon
+
[urgency_critical]
background = "#900000"
foreground = "#ffffff"
frame_color = "#ff0000"
timeout = 0
+ # Icon for notifications with critical urgency, uncomment to enable
+ #default_icon = /path/to/icon
+
+# Every section that isn't one of the above is interpreted as a rules to
+# override settings for certain messages.
+#
+# Messages can be matched by
+# appname (discouraged, see desktop_entry)
+# body
+# category
+# desktop_entry
+# icon
+# match_transient
+# msg_urgency
+# stack_tag
+# summary
+#
+# and you can override the
+# background
+# foreground
+# format
+# frame_color
+# fullscreen
+# new_icon
+# set_stack_tag
+# set_transient
+# set_category
+# timeout
+# urgency
+# icon_position
+# skip_display
+# history_ignore
+# action_name
+# word_wrap
+# ellipsize
+# alignment
+# hide_text
+#
+# Shell-like globbing will get expanded.
+#
+# Instead of the appname filter, it's recommended to use the desktop_entry filter.
+# GLib based applications export their desktop-entry name. In comparison to the appname,
+# the desktop-entry won't get localized.
+#
+# SCRIPTING
+# You can specify a script that gets run when the rule matches by
+# setting the "script" option.
+# The script will be called as follows:
+# script appname summary body icon urgency
+# where urgency can be "LOW", "NORMAL" or "CRITICAL".
+#
+# NOTE: It might be helpful to run dunst -print in a terminal in order
+# to find fitting options for rules.
+
+# Disable the transient hint so that idle_threshold cannot be bypassed from the
+# client
+#[transient_disable]
+# match_transient = yes
+# set_transient = no
+#
+# Make the handling of transient notifications more strict by making them not
+# be placed in history.
+#[transient_history_ignore]
+# match_transient = yes
+# history_ignore = yes
+
+# fullscreen values
+# show: show the notifications, regardless if there is a fullscreen window opened
+# delay: displays the new notification, if there is no fullscreen window active
+# If the notification is already drawn, it won't get undrawn.
+# pushback: same as delay, but when switching into fullscreen, the notification will get
+# withdrawn from screen again and will get delayed like a new notification
+#[fullscreen_delay_everything]
+# fullscreen = delay
+#[fullscreen_show_critical]
+# msg_urgency = critical
+# fullscreen = show
+
+#[espeak]
+# summary = "*"
+# script = dunst_espeak.sh
+
+#[script-test]
+# summary = "*script*"
+# script = dunst_test.sh
+
+#[ignore]
+# # This notification will not be displayed
+# summary = "foobar"
+# skip_display = true
+
+#[history-ignore]
+# # This notification will not be saved in history
+# summary = "foobar"
+# history_ignore = yes
+
+#[skip-display]
+# # This notification will not be displayed, but will be included in the history
+# summary = "foobar"
+# skip_display = yes
+
+#[signed_on]
+# appname = Pidgin
+# summary = "*signed on*"
+# urgency = low
+#
+#[signed_off]
+# appname = Pidgin
+# summary = *signed off*
+# urgency = low
+#
+#[says]
+# appname = Pidgin
+# summary = *says*
+# urgency = critical
+#
+#[twitter]
+# appname = Pidgin
+# summary = *twitter.com*
+# urgency = normal
+#
+#[stack-volumes]
+# appname = "some_volume_notifiers"
+# set_stack_tag = "volume"
+#
+# vim: ft=cfg
+
+
+# above are the defaults from t12 in /etc/xdg/dunst/dunstrc,
+# except i changed offset from the default of
+# offset = 10x50
-# above are the defaults from t11 in /etc/xdg/dunst/dunstrc
[play_sound]
stack_tag = "profanity"
script = /b/ds/sound-alert
-
# default light blue is too light
#[urgency_normal]
# background = "#335EA8"