lots: shellcheck, streaming stuff, fixes
authorIan Kelling <ian@iankelling.org>
Mon, 15 Apr 2024 14:47:21 +0000 (10:47 -0400)
committerIan Kelling <ian@iankelling.org>
Mon, 15 Apr 2024 14:47:21 +0000 (10:47 -0400)
65 files changed:
.bash_profile
beet-data
brc
brc2
brcrun
check-radicale
check-remote-mailqs
check-stale-alerts
clip-hc [new file with mode: 0755]
clip-sad [new file with mode: 0755]
clip-up [new file with mode: 0755]
conflink
dall
demohost-mount
desktop-20-autostart.sh
disabled/maru-init [moved from maru-init with 100% similarity]
disabled/mastodon-upgrade [moved from mastodon-upgrade with 100% similarity]
disabled/offlineimap-sync [moved from offlineimap-sync with 100% similarity]
distro-begin
distro-end
dsremote
dynamic-ip-update
exim-nn-iptables
filesystem/etc/nginx/conf.d/rtmp.conf [deleted file]
filesystem/etc/systemd/system/icecast2.service.d/override.conf [new file with mode: 0644]
filesystem/usr/local/bin/abrowser
filesystem/usr/local/bin/myupgrade
fixvpndns
gitslink
i3-auto-layout-toggle [new file with mode: 0755]
i3-maybe-double-move [new file with mode: 0755]
i3-mouse-warp [new file with mode: 0755]
i3-pull [new file with mode: 0755]
i3-split-maybe [new file with mode: 0755]
i3-sway/common.conf
i3-sway/i3.conf
iboot
ic-tmp-setup [new file with mode: 0755]
input-setup
ip6tables-exim
iptables-exim
keyscript-on
mail-cert-cron
mount-latest-remote
mount-latest-subvol
my-update-info-dir
myi3status
nextcloud-setup
obs [new file with mode: 0755]
obs-auto-scene-switch-toggle [new file with mode: 0755]
obs-i3-interlude [new file with mode: 0755]
obs-i3-monitor [new file with mode: 0755]
pkgs
schrootupdate
ssh-emacs-setup
subdir_files/.config/mpv/mpv.conf
switch-mail-host
system-status
trusted-network
vpn-mail-forward
vpn-static-ip
zboot
zboot-chroot
ziva-backup-check
ziva-screen

index ce98e54b7df33c7aaff3fa172e9126dbbdecff5b..ef517f2383dff9ae318f714b0c99b9997784b88a 100644 (file)
@@ -1,4 +1,5 @@
-# man bash covers everything comprehensively of course.  i use ~/.bash_profile
+#!/bin/bash
+# info bash covers everything comprehensively of course.  i use ~/.bash_profile
 # to source bashrc, and .profile just echos that the normal bash startup process
 # is not happening.  I don't source bashrc in posix mode based on debian's
 # default, and posix mode is quirky, doesn't seem worth figuring it out This
@@ -34,6 +35,7 @@ HISTCONTROL=ignoredups
 HISTIGNORE='pass *:[ ]*:otp *:oathtool *'
 
 
+# shellcheck source=/a/bin/ds/.bashrc
 [[ -f ~/.bashrc ]] && . ~/.bashrc
 # ensure no bad programs appending to this file will have an affect
 return 0
index c030efd59a390e47993dc1f989d0863479ecae5b..bdfb32dad38e64acdfcc786a94150495d8f8f73d 100644 (file)
--- a/beet-data
+++ b/beet-data
@@ -21,6 +21,7 @@ nav_tags=(
   run
 )
 
+
 pl_tags=(
   "${nav_tags[@]}"
   # alternate version of a song we already have which isn't as good
diff --git a/brc b/brc
index 2a81b25fa369f557d373f431d3c56400f61e9707..f0b57f8cc1558918fdd34ff410da566854024207 100644 (file)
--- a/brc
+++ b/brc
@@ -347,6 +347,9 @@ if [[ $SOE ]]; then
   fi
 fi
 
+# go exists here
+path-add --ifexists /usr/local/go/bin
+
 
 mysrc() {
   local path dir file
@@ -870,9 +873,21 @@ khfix() {
 a() {
   local x
   x=$(readlink -nf "${1:-$PWD}")
-  # yes, its kinda dumb that xclip/xsel cant do this in one invocation
-  echo -n "$x" | xclip -selection clipboard
-  echo -n "$x" | xclip
+  # yes, its kinda dumb that xclip/xsel cant do this in one invocation.
+  # And, summarizing this:
+  # https://askubuntu.com/questions/705620/xclip-vs-xsel
+  # xclip has a few more options. xclip has a bug in tmux / forwarded x sessions.
+  cbs "$x"
+}
+
+# clipboard a string (into selection & clipboard buffer)
+cbs() {
+  # yes, its kinda dumb that xclip/xsel cant do this in one invocation.
+  # And, summarizing this:
+  # https://askubuntu.com/questions/705620/xclip-vs-xsel
+  # xclip has a few more options. xclip has a bug in tmux / forwarded x sessions.
+  printf "%s" "$*" | xclip -selection clipboard
+  printf "%s" "$*" | xclip
 }
 
 # a1 = awk {print $1}
@@ -1609,8 +1624,9 @@ gl() {
   "$@" &> /a/tmp/gtmp
   g /a/tmp/gtmp
 }
-# g command substitution
+# g command substitution.
 gc() {
+  # shellcheck disable=SC2046 # i want word splitting for this hackery
   g $("$@")
 }
 
@@ -1720,7 +1736,7 @@ go-github-install() {
   file_prefix=$2
   file_suffix=$3
   tmp="${file_prefix##*[[:alnum:]]}"
-  targetf="${file_prefix%$tmp}"
+  targetf="${file_prefix%"$tmp"}"
   echo targetf: $targetf
   github-release-dl "$@"
   files=(./*)
@@ -2429,15 +2445,16 @@ sgu() {
 
 
 sk() {
-  # disable a warning with:
-  # shellcheck disable=SC2206 # reasoning
-
-  # see bash-template/style-guide.md for justifications
-
-  local quotes others
+  # see https://savannah.gnu.org/maintenance/fsf/bash-style-guide/ for justifications
+  local quotes others ret
   quotes=2048,2068,2086,2206,2254
   others=2029,2032,2033,2054,2164,
-  shellcheck -W 999 -x -e $quotes,$others "$@" || return $?
+  shellcheck -W 999 -x -e $quotes,$others "$@" || ret=$?
+  if (( ret >= 1 )); then
+    echo "A template comment to disable is now in clipboard. eg: # shellcheck disable=SC2206 # reason"
+    cbs "# shellcheck disable=SC"
+    return $ret
+  fi
 }
 # sk with quotes. For checking scripts that we expect to take untrusted
 # input in order to verify we quoted vars.
@@ -2823,7 +2840,7 @@ psoff() {
 pson() {
   PROMPT_COMMAND=(prompt-command)
   if [[ $TERM == *(screen*|xterm*|rxvt*) ]]; then
-    trap 'settitle "$BASH_COMMAND"' DEBUG
+    trap 'auto-window-title "$BASH_COMMAND"' DEBUG
   fi
 }
 
@@ -3125,6 +3142,12 @@ EOF
   done
 }
 
+# note, there is also the tool gron which is meant for this, but
+# this is good enough to not bother installing another tool
+jq-lines() {
+  # https://stackoverflow.com/questions/59700329/how-to-print-path-and-key-values-of-json-file-using-jq
+  jq --stream -r 'select(.[1]|scalars!=null) | "\(.[0]|join(".")): \(.[1]|tojson)"' "$@"
+}
 
 tsr() { # ts run
   "$@" |& ts || return $?
@@ -3284,7 +3307,7 @@ if [[ $- == *i* ]]; then
   fi
 
   # make the titlebar be the last command and the current directory.
-  settitle () {
+  auto-window-title () {
 
 
     # These are some checks to help ensure we dont set the title at
@@ -3309,7 +3332,7 @@ if [[ $- == *i* ]]; then
   # condition from the screen man page i think.
   # note: duplicated in tx()
   if [[ $TERM == *(screen*|xterm*|rxvt*) ]]; then
-    trap 'settitle "$BASH_COMMAND"' DEBUG
+    trap 'auto-window-title "$BASH_COMMAND"' DEBUG
   else
     trap DEBUG
   fi
diff --git a/brc2 b/brc2
index ec5969fef4929276b151883fe698fd24d3c78c5e..1c57452b1cb82c01cfd33554bc50573ab8eeb82a 100644 (file)
--- a/brc2
+++ b/brc2
@@ -463,7 +463,7 @@ glue() {
 
 # usage: see above
 _iki-convert() {
-  local url url_prefix path input err repo_dir dir url_dir url name
+  local url url_prefix path input repo_dir dir url_dir url name
   url_prefix="$1"
   name="${url_prefix%%.*}"
   repo_dir="/f/$name"
@@ -476,8 +476,16 @@ _iki-convert() {
   case $input in
     http*)
       path="$repo_dir/${input##http*://"$url_prefix"/}"
+      # for files like x.jpg, we dont need to convert the extension.
       if [[ $path == */ ]]; then
         path=${path%/}.mdwn
+        # brains adds trailing slash, but without trailing is still
+        # valid. We can't be totally sure whether to add mdwn, but we
+        # can guess based on the existence of the file. We can't be sure
+        # because it could be a file like x.jpg, that we just don't have
+        # in our local repo.
+        elif [[ ! -f $path && -e $path.mdwn ]]; then
+        path=${path}.mdwn
       fi
       j printf "%s\n" "$path"
       ;;
@@ -485,7 +493,9 @@ _iki-convert() {
       path=$(fp "$input")
       url_dir=$(echo "$path" | sed -r "s,^(/a)?$repo_dir/,,")
       url="https://$url_prefix/$url_dir"
-      url="${url%.mdwn}/"
+      if [[ $url == *.mdwn ]]; then
+        url="${url%.mdwn}/"
+      fi
       j echo "$url"
       ;;
   esac
@@ -748,6 +758,7 @@ mpvrpc-percent-pos() {
 # background, this relies on how ps converts newlines in arguments to spaces, and
 # assumes we won't be searching for a command with spaces in its arguments
 rinr() {
+  # shellcheck disable=SC2009 # pgrep has no fixed string option, plus see above.
   if ps h -o args -C "${1##*/}" | grep -Fxqv "$*" &>/dev/null || [[ $? == 141 ]]; then
     "$@"
   fi
@@ -780,7 +791,7 @@ mpvrpc-loadfile() {
     finalpath="$cachedir${path#/i/m}"
     rowir rsync --partial -a --inplace --mkpath "b8.nz:$path" "$finalpath"
     finalnextpath="$cachedir${nextpath#/i/m}"
-    count=$(pgrep -a -f "^rsync --partial -a --inplace --mkpath $cachdir" || [[ $? == 1 ]] )
+    count=$(pgrep -a -f "^rsync --partial -a --inplace --mkpath $cachedir" || [[ $? == 1 ]] )
     # allow us to start 2 rsyncs in the background
     if [[ $count == [01] ]]; then
       rinr rsync --partial -a --inplace --mkpath "b8.nz:$nextpath" "$finalnextpath" &
@@ -1761,7 +1772,8 @@ bindpush() {
   dsign iankelling.org expertpathologyreview.com zroe.org amnimal.ninja
   lipush
   for h in li bk; do
-    m sl $h.b8.nz <<'EOF'
+    e sshing $h
+    ssh $h.b8.nz <<'EOF'
 source ~/.bashrc
 m dnsup
 EOF
@@ -1770,7 +1782,8 @@ EOF
 bindpushb8() {
   lipush
   for h in li bk; do
-    m sl $h <<'EOF'
+    e sshing $h
+    ssh $h.b8.nz <<'EOF'
 source ~/.bashrc
 m dnsb8
 EOF
@@ -2932,6 +2945,9 @@ mpvgpu() {
 mpvd() {
   mpv --profile=d "$@";
 }
+mpva() {
+  mpv --profile=a "$@";
+}
 # mpv all media files in . or $1
 mpvm() {
   local -a extensions arg
@@ -3411,8 +3427,6 @@ spd() {
 }
 
 spamf() { # spamtest on FILE
-  local spamcpre spamdpid
-
   if (( $# != 1 )); then
     e spamtest error: expected 1 arg, filename >&2
     return 1
@@ -4016,12 +4030,6 @@ vrun() {
   "$@"
 }
 
-f=/a/f/ansible-configs/files/common/etc/fsf-workstation-bashrc.sh
-if [[ -e $f ]]; then
-  # shellcheck disable=SC1090
-  source $f
-fi
-
 electrum() {
   # https://electrum.readthedocs.io/en/latest/tor.html
   # https://github.com/spesmilo/electrum-docs/issues/129
@@ -4039,23 +4047,34 @@ rgm() {
 }
 
 # re all my files more expansively
+
 rem() {
   local paths
   paths="/p/c /b/"
   find $paths -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 | grep -iP --color=auto -- "$*" ||:
-  rgv -- "$*" $paths /a/t.org /p/w.org /a/work.org ||:
+  rgv $local_rgv_args -g "!bash_unpublished" -- "$*" $paths /a/work.org ||:
 }
-reml() { # with limit to 5 matches per file
+reml() { # rem with limit to 5 matches per file
+  local_rgv_args="-m 5"
+  rem "$@"
+}
+
+rep() {
   local paths
-  paths="/p/c /b"
+  paths="/p/c"
   find $paths -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 | grep -iP --color=auto -- "$*" ||:
-  rgv -m 5 -- "$*" $paths /a/t.org /p/w.org /a/work.org ||:
+  rgv $local_rgv_args -- "$*" $paths /a/t.org /p/w.org ||:
+}
+repl() { # rem with limit to 5 matches per file
+  local local_rgv_args="-m 5"
+  rem "$@"
 }
 
+
 # re on common fsf files
 ref() {
   local paths
@@ -4202,9 +4221,6 @@ mypyenvinit () {
 }
 
 
-export GOPATH=$HOME/go
-path-add $GOPATH/bin
-path-add /usr/local/go/bin
 
 # I have the git repo and a release. either one should work.
 # I have both because I was trying to solve an issue that
@@ -4366,6 +4382,54 @@ ftoc() {
   units "tempF($1)" tempC
 }
 
+# requires dns/firewall setup first
+local-icecast() {
+  web-conf -e ian@iankelling.org -f 8000 - apache2 live.iankelling.org  <<'EOF'
+<Location "/fsf.webm">
+AuthType Basic
+AuthName "basic_auth"
+# created with
+# htpasswd -c icecast-fsf-htpasswd USERNAME
+AuthUserFile "/etc/icecast-fsf-htpasswd"
+Require valid-user
+</Location>
+<Location "/fsf-tech.webm">
+AuthType Basic
+AuthName "basic_auth"
+AuthUserFile "/etc/icecast-fsf-tech-htpasswd"
+Require valid-user
+</Location>
+EOF
+}
+
+# obs screen switching of
+obof() {
+  ls -l /tmp/no-obs-auto-scene-switch
+  touch /tmp/no-obs-auto-scene-switch
+}
+# obs screen switching on
+obon() {
+  ls -l /tmp/no-obs-auto-scene-switch
+  if [[ -e /tmp/no-obs-auto-scene-switch ]]; then
+    rm -f /tmp/no-obs-auto-scene-switch
+  fi
+}
+
+obs-gen-profiles() {
+  local p=/p/c/basic/profiles
+  sed 's/fsf-sysops/fsf-tech/g' $p/fsfsysops/basic.ini >$p/fsftech/basic.ini
+  sed 's/fsf-sysops/fsf/g' $p/fsfsysops/basic.ini >$p/fsf/basic.ini
+}
+
+# terminal clear. like clear, but put the prompt at the bottom,
+# useful for obs streaming the bottom half of a terminal window.
+tclear() {
+  for ((i=i; i<COLUMNS; i++)); do
+    echo
+  done
+}
+
+
 export BASEFILE_DIR=/a/bin/fai-basefiles
 
 #export ANDROID_HOME=/a/opt/android-home
diff --git a/brcrun b/brcrun
index 4ede74ea715afb8a8b2ac384dae9c10aa7d05ce5..b8e4c88bbe5ce5b20d3e788807e77b81e9d14237 100755 (executable)
--- a/brcrun
+++ b/brcrun
@@ -1,3 +1,4 @@
 #!/bin/bash
+# shellcheck disable=SC1090
 . ~/.bashrc
 "$@"
index 99599a51ce86cc9e130ec5e6aa3fa305d17cda70..11860a6dc55207478322fc143042f1c49b76d377 100755 (executable)
@@ -14,7 +14,7 @@ fi
 # zerod out, by picking an amount that we dont expect to go below
 # anytime soon as of 2022.
 
-count=$(find /o/radicale/collections -type f | grep -v cache | wc -l)
+count=$(find /o/radicale/collections -type f | grep -cv cache)
 
 if (( count < 220 )); then
   echo "unexpected file count=$count < 220"
index 047e8b7ccae997a5a77451a40b0f036387cfcf15..eb8e20adf03a801e6ec1e37557123355343978b0 100755 (executable)
@@ -27,7 +27,7 @@ for h in bk je li x3wg kdwg sywg; do
   else
     if [[ -s $statefile ]]; then
       logsec=$(date +%s -d "$(head -n1 $statefile | awk '{print $1,$2}')")
-      case h in
+      case $h in
         frodo)
           hours=200
           ;;
index f0d84815121b49fe9730c00609aae9e10398cee8..cd42122f0791f727b6a11a195502e3c22fb3ed4a 100755 (executable)
@@ -4,7 +4,7 @@
 if [[ ! -e /dev/shm/iank-status ]]; then
   exit 0
 fi
-eval $(< /dev/shm/iank-status)
+eval "$(< /dev/shm/iank-status)"
 
 dirs=()
 for d in /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state; do
diff --git a/clip-hc b/clip-hc
new file mode 100755 (executable)
index 0000000..ed8e738
--- /dev/null
+++ b/clip-hc
@@ -0,0 +1,19 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+
+cd /a/bin/data/clips/hc
+
+if pgrep mpv; then
+  pkill mpv
+  exit 0
+fi
+
+clip=$(find . -type f -printf '%f\n' | \
+         { if [[ -e /tmp/last-hc ]]; then
+             sed "/^$(cat /tmp/last-hc)\$/d"
+           else
+             cat
+           fi ; } | \
+             shuf | head -n1)
+echo $clip >/tmp/last-hc
+mpv --profile=a $clip
diff --git a/clip-sad b/clip-sad
new file mode 100755 (executable)
index 0000000..e1ce318
--- /dev/null
+++ b/clip-sad
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+cd /a/bin/data/clips/sad
+
+if pgrep mpv; then
+  pkill mpv
+  exit 0
+fi
+
+clip=$(find . -type f -printf '%f\n' | \
+         { if [[ -e /tmp/last-sad ]]; then
+             sed "/^$(cat /tmp/last-sad)\$/d"
+           else
+             cat
+           fi ; } | \
+             shuf | head -n1)
+echo $clip >/tmp/last-sad
+mpv --profile=a $clip
diff --git a/clip-up b/clip-up
new file mode 100755 (executable)
index 0000000..dea5f1d
--- /dev/null
+++ b/clip-up
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+cd /a/bin/data/clips/up
+
+if pgrep mpv; then
+  pkill mpv
+  exit 0
+fi
+
+if [[ ! -s /tmp/last-up ]]; then
+  find . -type f -printf '%f\n' | shuf > /tmp/last-up
+fi
+clip=$(head -n1 /tmp/last-up)
+tail -n+2 /tmp/last-up | sponge /tmp/last-up
+
+# clip=$(ls -1 . | \
+  #          { if [[ -e /tmp/last-up ]]; then
+#              sed "/^$(cat /tmp/last-up)\$/d"
+#            else
+#              cat
+#            fi ; } | \
+  #              shuf | head -n1)
+# echo $clip >/tmp/last-up
+
+mpv --profile=a $clip
index d661e172dfd5a5b1d2f5790236221dfc59f62232..568152989a5ade5a1eb4c1a9a18c91248403a2be 100755 (executable)
--- a/conflink
+++ b/conflink
@@ -94,7 +94,7 @@ subdir-link-r() {
     local fullpath
     fullpath="$(readlink -f "$path")"
     if [[ -f $path || $(dirname "$fullpath") == "$below" ]]; then
-      m lnf -T "$path" "$HOME/${path#$root/}"
+      m lnf -T "$path" "$HOME/${path#"$root/"}"
     elif [[ -d "$path" ]]; then
       subdir-link-r "$root" "$path"
     fi
@@ -223,6 +223,7 @@ case $user in
       m s chgrp -R bind $f
       m s chmod g+w $f
     fi
+    # shellcheck disable=SC2016 # obviously expected
     s bash -c 'shopt -s nullglob; for f in /etc/bind/*.key /etc/bind/*.private /etc/bind/key.*; do chgrp bind $f; done'
     if [[ -e /etc/caldav-htpasswd ]] && getent group www-data &>/dev/null; then
       s chgrp www-data /etc/caldav-htpasswd
@@ -244,6 +245,10 @@ case $user in
       s rsync -clpgoDiSAX --chmod=Dg-s --chown=bitcoin:bitcoin /p/c/user-specific/bitcoin/settings.json /var/lib/bitcoind
       s rsync -rclpgoDiSAX --chmod=Dg-s --chown=root:bitcoin /p/c/user-specific/bitcoin/bitcoin /etc
     fi
+    # this folder strangely requires ownership as icecast2
+    if [[ -d /etc/icecast2 && -f /p/c/icecast.xml ]]; then
+      m s rsync -rclgoDiSAX --chmod=0644 --chown=root:root /p/c/icecast.xml /etc/icecast2
+    fi
     ##### end special extra stuff #####
 
     if ! $fast; then
diff --git a/dall b/dall
index 3ed8d4480983282e8114d05074d43911011ef264..d054f9dacafe71315dfc60aab46771b635852bbb 100755 (executable)
--- a/dall
+++ b/dall
@@ -5,7 +5,7 @@ shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
 set -eE -o pipefail
 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
 
-readonly this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"
+readonly this_file; this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"
 readonly this_dir="${this_file%/*}"
 cd "$this_dir"
 ./distro-begin
index 90d2b42497cedfa56e7420e8a74a235c49a7935e..91e984fdcadcb43ec0f745fcd7915034a82ac98d 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
+# shellcheck source=/a/bin/ds/.bashrc
 if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi
 
 [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
index 0a3d139cb161d75c562211c46144f8779b96d7da..278da29e0e606ca0e605720a9e8e28123ef5b775 100755 (executable)
 date "+%A, %B %d, %r, %S seconds" > /tmp/desktop-20-autostart-log
 
 
-# first 2 alternatives showed under ubuntu 14.04, second 2 under arch at 11/2015
-if [[ $1 ]]; then
-  right_monitor_rotation=left
-else
-  right_monitor_rotation=normal
-fi
-
-
 if ! xout="$(xrandr)"; then
   # under wayland
   exit 0
similarity index 100%
rename from maru-init
rename to disabled/maru-init
similarity index 100%
rename from mastodon-upgrade
rename to disabled/mastodon-upgrade
similarity index 100%
rename from offlineimap-sync
rename to disabled/offlineimap-sync
index 4104e0015ce4ee1f44d1971696b1c1530be70087..61d8f8d002b56d3924c8547dade334ce76b99f59 100755 (executable)
@@ -481,6 +481,7 @@ if isarch; then
 fi
 
 #### update all packages
+# shellcheck disable=SC2119 # obvious
 pup
 
 
@@ -708,8 +709,7 @@ if has_monitor; then
 
 
   ###### install X
-  # no recommends due to this bug: https://trisquel.info/en/issues/26525
-  pi --no-install-recommends i3
+  pi i3
 
   ##### install xinput
   case $(distro-name) in
index 16fc7a5b0afbcfe6e46291c24ce4edbf3a1e744d..e5770d48647187929627419eecbeabd9928638e0 100755 (executable)
@@ -176,11 +176,13 @@ EOF
       fi
     done
     if $doupdate; then
-      cd $(mktemp -d)
+      tmpdir=$(mktemp -d)
+      cd $tmpdir
       p download debian-archive-keyring
       s dpkg -i debian-archive-keyring
       p update
       cd -
+      rm -rf $tmpdir
     fi
 
     if [[ ! -e /usr/share/debootstrap/scripts/bookworm ]]; then
@@ -756,6 +758,35 @@ esac
 case $distro in
   trisquel|ubuntu)
 
+
+    ## one time setup thing I did
+    # c /a/opt/obs-cmd/
+    # cargo build --release
+    # cp target/release/obs-cmd ../bin
+    #
+    ## in obs, tools -> websocket server settings -> generate/copy password
+    #
+    # note: obs-studio on gnu does not support webrtc, it seems mainly because
+    # libdatachannel is not packaged. If it was, it would just need to do
+    # apt source obs-studio, obs-studio-30.1.1/debian/rules set -DENABLE_WEBRTC=ON
+    #
+    # I did manage to build libdatachannel following its instructions, then make install,
+    # then obs failed due to nvidia. found those options to disable with
+    # rg 'option\(ENABLE' | gr nv, then build obs like so:
+    #
+    # cmake -DLINUX_PORTABLE=ON -DCMAKE_INSTALL_PREFIX="${HOME}/obs-studio-portable" -DENABLE_BROWSER=OFF -DENABLE_AJA=OFF -DENABLE_NEW_MPEGTS_OUTPUT=OFF -DENABLE_WEBRTC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DENABLE_NVVFX=OFF -DENABLE_NVAFX=OFF -DENABLE_NATIVE_NVENC=OFF  ..
+    #
+    #
+    #
+    # however, I didn't end up trying it out.
+    #
+    # note, in terminal source, i setup a transform so it would show the
+    # bottom 1080p section of the terminal instead of the top if the
+    # screen was bigger. click like 2 times in the preview so the red
+    # lines show up, right click, edit transform (or ctrl-e). bounding
+    # box type: scale to width of bounds. alignment in bounding box:
+    # bottom left. bounding box size 1920 x 1080.
+
     # ppa:obsproject/obs-studio
     if [[ ! -s /etc/apt/sources.list.d/obs.list ]]; then
       # https://blog.zackad.dev/en/2017/08/17/add-ppa-simple-way.html
@@ -767,6 +798,7 @@ EOF
       p update
     fi
     ;;
+
 esac
 
 case $codename_compat in
@@ -2015,9 +2047,39 @@ esac
 # `mpv --cache=no` had about 2.5 sec latency vs 4 seconds.
 # Then I discovered this command which had about .5 sec latency:
 #ffplay -f live_flv -fast -x 1280 -y 720 -fflags nobuffer -flags low_delay -strict experimental -vf "setpts=N/60/TB" -af "asetpts=N/60/TB" -noframedrop -i rtmp://url_here
+## a lot of those args arent needed, here is what I ended up with:
+# #ffplay -f live_flv -fflags nobuffer -flags low_delay -i rtmp://localhost/live
 #
-pi nginx libnginx-mod-rtmp
-
+# A problem with rtmp is that it doesn't support vp8/vp9, requiring the partly patent encumbered h264.
+# Looking at alternative protocols: dash & hls are both high latency, I tested dash with the nginx-rtmp
+# module and got about 5 seconds of latency, web results imply that is normal.
+#
+# Webrtc is what jitsi & bbb use, but an annoying thing is that
+# generally requires a web browser with javascript, or some special
+# client, and afaik, it has a smaller limit on number of clients.
+#
+# Another option is to try rtp/rtsp, there are some servers here:
+# https://en.wikipedia.org/wiki/Real-Time_Streaming_Protocol
+
+
+## reference for setting up rtmp
+# pi nginx libnginx-mod-rtmp
+# cat >/etc/nginx/modules-enabled/rtmp.conf <<'EOF'
+## based on https://opensource.com/article/19/1/basic-live-video-streaming-server#comments
+## and https://github.com/arut/nginx-rtmp-module/wiki/Directives
+
+# rtmp {
+#     allow publish 127.0.0.1;
+#     deny publish all;
+#     server {
+#         listen 1935;
+#         application live {
+#             live on;
+#             record off;
+#         }
+#     }
+# }
+# EOF
 
 ### end live streaming ###
 
@@ -2091,6 +2153,13 @@ m /a/bin/buildscripts/tor-browser
 s ln -sf /a/opt/tor-browser/Browser/start-tor-browser /usr/local/bin
 
 
+case $HOSTNAME in
+  kd)
+    web-conf -p 4500 -f 4533 -e ian@iankelling.org apache2 b8.nz
+    sgo navidrome
+    ;;
+esac
+
 # nfs server
 pi-nostart nfs-kernel-server
 
index 21767404a53cfed9b1c045d79aa124f7f541c3f6..ec8b2d269e6669bec6f21542ff4e9e30e4f7812c 100755 (executable)
--- a/dsremote
+++ b/dsremote
@@ -13,6 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# shellcheck source=/a/bin/ds/.bashrc
 if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi
 
 set -eE -o pipefail
index c725682b5e02b63eda4d9d80305cc97b28d81b84..b6dfa09e940b6a9ca8dc550ee9e57e4f01f3b123 100755 (executable)
@@ -102,7 +102,7 @@ main() {
       return 0
     fi
     if ip4=$(curl --connect-timeout 10 -s4 https://iankelling.org/cgi/pubip); then
-      if $force || [[ $cur4 && $ip4 && $cur4 != $ip4 ]]; then
+      if $force || [[ $cur4 && $ip4 && $cur4 != "$ip4" ]]; then
         up4=true # update ipv4
       fi
     fi
@@ -120,7 +120,7 @@ main() {
     # we use slaac with privacy extension, so get our less private more permanent address
     mac=$(cat /sys/class/net/$dev/address)
 
-    IFS=: read -a f <<<$mac; set -- ${f[@]}
+    IFS=: read -ra f <<<$mac; set -- ${f[@]}
     ip6=${out6%:*:*:*:*}:$(printf %x $((0x$1 + 2)))$2:$3'ff:fe'$4:$5$6
     # in case we aren't using slaac
     if ! ip a | grep "^ *inet6 $ip6/" &>/dev/null; then
@@ -128,7 +128,7 @@ main() {
     fi
   fi
 
-  if $force || [[ $cur6 != $ip6 ]]; then
+  if $force || [[ $cur6 != "$ip6" ]]; then
     up6=true
   fi
 
@@ -146,14 +146,14 @@ main() {
   # "${SSH_CLIENT%% *}
   # to update bind if needed.
 
-  f=$(mktemp)
-  cat >>$f <<EOF
+  tmpf=$(mktemp)
+  cat >>$tmpf <<EOF
 server iankelling.org
 zone b8.nz
 EOF
 
   if $up4; then
-    cat >>$f <<EOF
+    cat >>$tmpf <<EOF
 update delete $dynhost. A
 update add $dynhost. 300 A $ip4
 update delete $dyndomain. A
@@ -163,31 +163,32 @@ EOF
 
   if $up6; then
     if [[ $ip6 ]]; then
-      cat >>$f <<EOF
+      cat >>$tmpf <<EOF
 update delete $fqdn. AAAA
 update add $fqdn. 60 AAAA $ip6
 EOF
     else
-      cat >>$f <<EOF
+      cat >>$tmpf <<EOF
 update delete $fqdn. AAAA
 EOF
     fi
   fi
 
-  cat >>$f <<EOF
+  cat >>$tmpf <<EOF
 show
 send
 answer
 quit
 EOF
 
-  chronic nsupdate $ip_arg -k /p/c/machine_specific/vps/filesystem/etc/bind/Kb8.nz.*.private <$f || nsupdate_fails=$((nsupdate_fails + 1))
-  sed -i 's/^server .*/server bk.b8.nz/' $f
-  chronic nsupdate $ip_arg -k /p/c/machine_specific/vps/filesystem/etc/bind/Kb8.nz.*.private <$f  || nsupdate_fails=$((nsupdate_fails + 1))
+  chronic nsupdate $ip_arg -k /p/c/machine_specific/vps/filesystem/etc/bind/Kb8.nz.*.private <$tmpf || nsupdate_fails=$((nsupdate_fails + 1))
+  sed -i 's/^server .*/server bk.b8.nz/' $tmpf
+  chronic nsupdate $ip_arg -k /p/c/machine_specific/vps/filesystem/etc/bind/Kb8.nz.*.private <$tmpf  || nsupdate_fails=$((nsupdate_fails + 1))
   if (( nsupdate_fails > nsupdate_fail_limit )); then
     echo error: nsupdate is persistently failing >&2
     exit 1
   fi
+  rm -f $tmpf
 }
 
 loop-main() {
@@ -219,7 +220,7 @@ exit 0
 
 
 #   f=key.b8.nz
-#   cat >$f <<EOF
+#   cat >$tmpf <<EOF
 # key b8.nz. {
 # algorithm HMAC-SHA512;
 # secret "$(awk '$1 == "Key:" {print $2}' Kb8.nz.*.private)";
index 119eaf0396daf3de56b2a6fdaed0b17505b1a167..67024c3f1622d894adca660d75a3077420f3798f 100755 (executable)
@@ -17,11 +17,11 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${P
 # on the systemd automatic restart. Ugh. So, better to use Wants instead
 # and this.
 
-if !/usr/sbin/iptables -C OUTPUT -p tcp -m tcp --dport 25 -o veth1-mail -j REJECT &>/dev/null; then
+if ! /usr/sbin/iptables -C OUTPUT -p tcp -m tcp --dport 25 -o veth1-mail -j REJECT &>/dev/null; then
  /usr/sbin/iptables -I OUTPUT -p tcp -m tcp --dport 25 -o veth1-mail -j REJECT
 fi
 
 
-if !/usr/sbin/ip6tables -C OUTPUT -p tcp -m tcp --dport 25 -o veth1-mail -j REJECT &>/dev/null; then
+if ! /usr/sbin/ip6tables -C OUTPUT -p tcp -m tcp --dport 25 -o veth1-mail -j REJECT &>/dev/null; then
  /usr/sbin/ip6tables -I OUTPUT -p tcp -m tcp --dport 25 -o veth1-mail -j REJECT
 fi
diff --git a/filesystem/etc/nginx/conf.d/rtmp.conf b/filesystem/etc/nginx/conf.d/rtmp.conf
deleted file mode 100644 (file)
index 4a47eda..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# based on https://opensource.com/article/19/1/basic-live-video-streaming-server#comments
-# and https://github.com/arut/nginx-rtmp-module/wiki/Directives
-rtmp {
-    allow publish 127.0.0.1;
-    deny publish all;
-    server {
-        listen 1935;
-        application live {
-            live on;
-            record off;
-        }
-    }
-}
diff --git a/filesystem/etc/systemd/system/icecast2.service.d/override.conf b/filesystem/etc/systemd/system/icecast2.service.d/override.conf
new file mode 100644 (file)
index 0000000..26de486
--- /dev/null
@@ -0,0 +1,2 @@
+[Service]
+ExecStartPre=+/b/ds/ic-tmp-setup
index 365911c54c77174c6f39263723a18dd431c75305..c84a6aebb73c13d659511c3771c6c4c4d1970387 100755 (executable)
@@ -16,9 +16,34 @@ PATH=$tmp
 # causes a new browser window to open, even if normally it would open a
 # new tab
 
+
+tmpf=$(mktemp)
+i3-msg -t get_tree | jq -e '.nodes[].nodes[].nodes[].nodes | [.[]] + ( [.[].nodes[]]) | .[] | select(.window_properties.class=="abrowser") | .id' | sort >$tmpf
+
 # prefer abrowser
 if type -P abrowser &>/dev/null; then
-  abrowser "$@"
+  abrowser "$@" &
 else
-  firefox "$@"
+  firefox "$@" &
 fi
+
+# .5 was too fast
+sleep 1
+# debug
+#printf "%s\n" "$*" >> /tmp/a
+if (( $# == 0 )) && ! i3-msg -t get_tree | jq --stream -r 'select(.[1]|scalars!=null) | "\(.[0]|join(".")): \(.[1]|tojson)"'  | grep 'marks.0: "abrowser"$' &>/dev/null; then
+  # explaining this jq nonsense. when the abrowser window starts, it
+  # might be in a vertical split container, and then it is nested down
+  # another level.  the best way I could find to look in both levels was
+  # to get both, then combine them with + (and you have to turn them
+  # into a single array instead of a list of arrays with [.[]], or else
+  # it will add the arrays a bunch of times and give several results.
+  # comm gives us just the new id.
+  id=$(i3-msg -t get_tree | jq -e '.nodes[].nodes[].nodes[].nodes | [.[]] + ( [.[].nodes[]]) | .[] | select(.window_properties.class=="abrowser") | .id' | comm -23 - $tmpf | head -n1)
+  rm -f $tmpf
+  if [[ $id ]]; then
+    i3-msg "[con_id=$id] mark abrowser"
+  fi
+fi
+
+wait
index 7a6c5623cf2758e95230507d098983251df0679b..f2c5aec0850209d76f080b98559c8f752be3b189 100755 (executable)
@@ -91,7 +91,7 @@ sleep 1
 # isolation instead of as part of bring up and down the whole desktop.
 # But, I'd rather something gets messed up than things not get
 # restarted.
-if ! /sbin/needrestart -p -l &>/dev/null; then
+if ! /sbin/needrestart -p &>/dev/null; then
   if [[ $hn == "$MAIL_HOST" || $hn == kd ]]; then
     # send us an email so we can decide what to do
     needrestart -r l
index a97b2bd1489633cba0bb7b3dbb3503bbac6a384f..d33797ad7426e746d6cc23c12bb29ba5d45cf482 100755 (executable)
--- a/fixvpndns
+++ b/fixvpndns
@@ -16,5 +16,5 @@ if ! resolvectl dnsovertls tunfsf &>/dev/null; then
   # resolvectl dnsovertls tunfsf ||:
   exit 0
 fi
-read _ link _ < <(resolvectl dnsovertls tunfsf)
+read -r _ link _ < <(resolvectl dnsovertls tunfsf)
 busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 org.freedesktop.resolve1.Manager SetLinkDNSOverTLS is $link no
index f44f2139a2b720ada824c4633011db10db4743f9..0616fe7e561825c7c3080e6e97c852ed62231a56 100755 (executable)
--- a/gitslink
+++ b/gitslink
@@ -20,7 +20,7 @@ source /a/bin/lnf/lnf >/dev/null ||:
 
 for x in !(unused|distro-setup|unfinished|queue|bash-template|buildscripts|crons|data|examples|log-quiet); do
   [[ -e $x/.git ]] || continue
-  for y in $x/*; do
+  for y in "$x"/*; do
     f=${y##*/}
     if [[ -x $y && ! -d $y ]]; then
       unset "existing[$f]"
diff --git a/i3-auto-layout-toggle b/i3-auto-layout-toggle
new file mode 100755 (executable)
index 0000000..e8a464d
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+
+f=/tmp/iank-i3-no-auto
+
+if [[ -e $f ]]; then
+  rm -f $f
+else
+  touch $f
+fi
diff --git a/i3-maybe-double-move b/i3-maybe-double-move
new file mode 100755 (executable)
index 0000000..3d25c3f
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+
+direction="$1"
+if i3-msg -t get_tree | jq -e -C '.nodes[].nodes[].nodes[].nodes[] | select((.nodes| length == 1) and (.nodes[0].focused == true))' &>/dev/null; then
+  i3-msg "move $direction; move $direction"
+else
+  i3-msg "move $direction"
+fi
diff --git a/i3-mouse-warp b/i3-mouse-warp
new file mode 100755 (executable)
index 0000000..99cdacf
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+
+## based on:
+## https://github.com/i3/i3/issues/2971
+
+window=$(xdotool getwindowfocus)
+
+# this brings in variables WIDTH and HEIGHT
+eval "$(xdotool getwindowgeometry --shell $window)"
+
+
+if (( HEIGHT > 100 )); then
+  TX=$(( WIDTH / 2))
+  TY=$(( HEIGHT / 2))
+
+  xdotool mousemove -window $window $TX $TY
+  # iank, original says "Check for height of 100 assumes that anything
+  # less than that means no window", and this condition is for "when I
+  # am navigating to a screen that does not have an open window on it". I don't think
+else
+  rect=$(i3-msg -t get_workspaces | jq -r '.[] | select(.focused==true).rect')
+
+  x=$(jq -r '.x' <<< $rect)
+  y=$(jq -r '.y' <<< $rect)
+  w=$(jq -r '.width' <<< $rect)
+  h=$(jq -r '.height' <<< $rect)
+  TX=$(( x + w / 2))
+  TY=$(( y + h / 2))
+  xdotool mousemove -window $window $TX $TY
+fi
diff --git a/i3-pull b/i3-pull
new file mode 100755 (executable)
index 0000000..87b7f07
--- /dev/null
+++ b/i3-pull
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# sometimes I want to pull in and sometimes I want to swap.
+
+set -e; . /usr/local/lib/bash-bear; set +e
+
+mark=$1
+h=$(i3-msg -t get_tree | jq -r ".. | select(.focused? == true) | .rect.height")
+
+cur_workspace=$(i3-msg -t get_workspaces | jq -r '.[] | select(.focused? == true) | .name')
+
+
+# 1080 = half the 4k height
+#if [[ $cur_workspace == 1 && $h ]] && (( h <= 1080 )); then
+if [[ $cur_workspace == 1 && $h ]]; then
+  i3-msg "swap container with mark $mark; [con_mark=\"$mark\"] focus"
+else
+  i3-msg '[con_mark="'$mark'"] move workspace current'
+fi
diff --git a/i3-split-maybe b/i3-split-maybe
new file mode 100755 (executable)
index 0000000..3cedb5c
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+set -e; . /usr/local/lib/bash-bear; set +e
+
+# We use this along with
+# /a/opt/i3-alternating-layout/alternating_layouts.py to anticipate when
+# we want to split/tab windows. There are 2 options of when to do it:
+# just after a window is created, or just before a window is
+# created. Doing it after a window is created allows you to move a
+# window into the split that only has 1 window, whereas the other way
+# doesn't. For my use cases, I think I don't really want to move it into
+# the split if it is a tabbed split.
+#
+# I have a keybind which disables both, it runs /b/ds/i3-auto-layout-toggle
+
+if [[ -e /tmp/iank-i3-no-auto ]]; then
+  exit 0
+fi
+
+
+tmp=$(mktemp)
+
+i3-msg -t get_workspaces | jq ".[]| select(.focused==true) | .rect | .width" >$tmp
+
+{ read -r screen_width; read -r screen_height; } <$tmp
+
+i3-msg -t get_tree | jq -r ".. | select(.focused? == true).rect | .width, .height" >$tmp
+
+half_w=$(( screen_width / 2 + 100 ))
+half_h=$(( screen_height / 2 + 100 ))
+
+
+{ read -r w; read -r h; } <$tmp
+
+
+if (( screen_width < 1920 )); then
+  # haven't considered this case yet
+  exit 0
+fi
+
+if (( w < half_w && h < half_h )); then
+  i3-msg "split vertical, layout tabbed"
+fi
+
+rm -f $tmp
index a658f3b218695581f1f89f36985f191d5eb41fdd..9e4cedcccf44836336889f260cf61d62c4a94a00 100644 (file)
@@ -1,12 +1,25 @@
 ####### DO NOT EDIT LIVE CONFIG. generated from /a/bin/distro-setup/i3-sway/gen #######
 
+# random thoughts: what to do with a window I don't have room for?
+# * I could tabify it
+# * I could split an existing window with it
+# * I could send it away to another workspace,
+# * I could resize it to be very small.
+
+
+# todo: think whether this is useful: https://github.com/tmfink/i3-wk-switch
+# todo: see comment by Jakstern551 here for tip about jumping to windows
+
 # https://i3wm.org/docs/userguide.html#keybindings
 #To get the current mapping of your keys, use xmodmap -pke. To
 #interactively enter a key and see what keysym it is configured to, use
 #xev.
 set $mod Mod4
 
-bindsym $mod+2 exec "pavucontrol"
+# for non-gui apps, use this.
+set $ex exec --no-startup-id
+
+bindsym $mod+2 $ex "/b/ds/i3-split-maybe"; exec "pavucontrol"
 # calling without -no-remote makes this to be the instance that links
 # will open in from other applications.
 bindsym $mod+3 exec "abrowser"
@@ -16,49 +29,59 @@ bindsym $mod+3 exec "abrowser"
 #bindsym $mod+3 exec "abrowser 2>&1 >/tmp/l"
 #bindsym $mod+3 exec "abrowser -no-remote -P sfw"
 bindsym $mod+4 exec "abrowser -no-remote -P firefox-main-profile"
-bindsym $mod+5 exec "/a/bin/ds/laptop-xrandr"
+# todo: figure out a stream delay & way to cut the stream.
+# settings, advanced, stream delay
+bindsym $mod+5 $ex "/a/bin/ds/obs-i3-interlude"
 bindsym $mod+6 exec "/usr/local/bin/start-tor-browser"
-#bindsym $mod+6 exec "/a/bin/redshift.sh"
-# bindsym $mod+equal exec "t s w; t in"
-# bindsym $mod+Home exec "t out"
-# #bindsym $mod+End exec "t s x; t in"
-# bindsym $mod+grave exec "t s lunch; t in; t out -a '45 minutes from now'"
+bindsym $mod+7 $ex "/a/bin/ds/laptop-xrandr"
+#bindsym $mod+6 $ex "/a/bin/redshift.sh"
+# bindsym $mod+equal $ex "t s w; t in"
+# bindsym $mod+Home $ex "t out"
+# #bindsym $mod+End $ex "t s x; t in"
+# bindsym $mod+grave $ex "t s lunch; t in; t out -a '45 minutes from now'"
 
 
 bindsym $mod+1 focus parent
-bindsym $mod+equal exec "dunstctl close-all"
+bindsym $mod+shift+1 focus child
+# undo split: https://github.com/i3/i3/issues/3808
+bindsym $mod+grave floating toggle; floating toggle
+bindsym $mod+equal $ex "dunstctl close-all"
 # move firefox to current workspace.
 # https://i3wm.org/docs/userguide.html#keybindings
 # get class with xprop, example output
 # WM_CLASS(STRING) = "irssi", "URxvt"
 # xprop |& grep WM_CLASS
-bindsym $mod+w [class="abrowser"] move workspace current
+bindsym $mod+w $ex i3-pull abrowser
+bindsym $mod+shift+w fullscreen toggle
 
-bindsym $mod+e fullscreen toggle
-bindsym $mod+r exec "/a/bin/ds/xl"
+bindsym $mod+e $ex i3-pull emacs
+bindsym $mod+shift+e unmark emacs; mark emacs
+bindsym $mod+r $ex "/a/bin/ds/xl"
 # todo, in newer i3, make this toggle split tabbed
-bindsym $mod+t layout toggle split
+bindsym $mod+t layout toggle splith splitv tabbed
 #bindsym $mod+Shift+t move workspace to output up
 bindsym $mod+Shift+t move workspace to output right
-bindsym $mod+g layout tabbed
+# there's a bug about this. it is not logical that there is no "split
+# tabbed", but you accomplish that by doing this.
+bindsym $mod+g split vertical, layout tabbed
+bindsym $mod+shift+g $ex "/b/ds/i3-auto-layout-toggle"
 
 # Use Mouse+$mod to drag floating windows to their wanted position
 floating_modifier $mod
 
-bindsym $mod+u focus left
-bindsym $mod+i focus right
-bindsym $mod+o focus up
-bindsym $mod+p focus down
+bindsym $mod+u focus left; $ex "i3-mouse-warp"
+bindsym $mod+i focus right; $ex "i3-mouse-warp"
+bindsym $mod+o focus up; $ex "i3-mouse-warp"
+bindsym $mod+p focus down; $ex "i3-mouse-warp"
 
-bindsym $mod+Left move left
-bindsym $mod+Right move right
-bindsym $mod+Up move up
-bindsym $mod+Down move down
+bindsym $mod+Left $ex "/a/exe/i3-maybe-double-move left"
+bindsym $mod+Right $ex "i3-maybe-double-move right"
+bindsym $mod+Up $ex "i3-maybe-double-move up"
+bindsym $mod+Down $ex "i3-maybe-double-move down"
 
-# switch to workspace
 bindsym $mod+Shift+a move container to workspace 4
 bindsym $mod+a workspace 4
-# move focused container to workspace
+
 bindsym $mod+Shift+s move container to workspace 3
 bindsym $mod+s workspace 3
 
@@ -78,13 +101,19 @@ bindsym $mod+x workspace 6
 # todo, in newer i3, make this split toggle
 bindsym $mod+v split vertical
 bindsym $mod+Shift+v split horizontal
+#
+## temp for testing, add antying here
+##bindsym $mod+shift+g
+bindsym $mod+b $ex i3-pull term
+bindsym $mod+shift+b unmark term; mark term
+# for use to cleanup extra emacs windows
 # https://faq.i3wm.org/question/7662/reverse-perl-matches-in-criteria-in-i3-config.1.html
 # I found their regex slightly wrong. This is a hacky way to
 # ignore my irc emacs instances, their window titles
 # are irc room names. Another way would be to hack on the
 # window title, or xprop stuff, but I figure I'm switching
 # to wayland soon, lets wait and see how things work there.
-bindsym $mod+b [class="Emacs" title="^(?!#[a-zA-Z][a-zA-Z-]*$)"] move workspace current
+bindsym $mod+shift+6 [class="Emacs" title="^(?!#[a-zA-Z][a-zA-Z-]*$)"] move workspace current
 
 bindsym $mod+c kill
 
@@ -99,32 +128,45 @@ bindsym $mod+8 workspace 9
 bindsym $mod+Shift+9 move container to workspace 10
 bindsym $mod+9 workspace 10
 
-b
-indsym $mod+Shift+m border toggle
+bindsym $mod+Shift+m border toggle
 
 # 65 = space.
-# toggle tiling / floating
-bindcode $mod+Shift+65 floating toggle
+# toggle tiling / floating.
+#
+# The idea here is: when floating a window, make it sticky and 1080p,
+# because the only reason we want to do this is to keep it on screen
+# when doing an obs broacast. When unfloating a window, just act as a
+# normal unfloat. There is a quirk with this: in a layout with 3 windows,
+# 2 stacked, 1 tall, floating and ufloating the tall one will make it
+# another stacked one, but still 1920x1080, you need to move it to the
+# right to get it back into its tall spot. I could automate this,
+# but I'm not bothering right now
+bindcode $mod+65 $ex obs-auto-scene-switch-toggle; floating toggle; sticky enable; resize set 1920 1080; move position 100 ppt 0 ppt
 
 # change focus between tiling / floating windows
-bindcode $mod+65 focus mode_toggle
+bindcode $mod+shift+65 focus mode_toggle
 # Use Mouse+$mod to drag floating windows to their wanted position
 floating_modifier $mod
 
-bindsym $mod+j exec emacsclient -c
-bindsym $mod+k exec konsole
-bindsym $mod+l exec dmenu_run
+bindsym $mod+shift+h $ex clip-hc
+bindsym $mod+j $ex emacsclient -c
+bindsym $mod+shift+j $ex clip-up
+bindsym $mod+k $ex konsole
+bindsym $mod+shift+k $ex mpv --profile=a /a/bin/data/clips/enter-in.flac
+bindsym $mod+l $ex dmenu_run
+bindsym $mod+shift+l $ex mpv --profile=a /a/bin/data/clips/tokyo-eye.flac
+bindsym $mod+shift+semicolon $ex clip-sad
 # note default is 27% on my system76. not sure if these
 # keybinds will screw up other laptop brightness keys.
-bindsym XF86MonBrightnessUp exec brightnessctl s +5%
-bindsym XF86MonBrightnessDown exec brightnessctl s 5%-
+bindsym XF86MonBrightnessUp $ex brightnessctl s +5%
+bindsym XF86MonBrightnessDown $ex brightnessctl s 5%-
 
 # Font for window titles. Will also be used by the bar unless a different font
 # is used in the bar {} block below.
-font pango:monospace 8
+font pango:monospace 7
 
 # todo: only available in newer i3n
-#hide_edge_borders smart
+hide_edge_borders vertical
 
 #exec --no-startup-id /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd
 
@@ -133,10 +175,11 @@ font pango:monospace 8
 
 
 # shortcut to selection widget (primary)
-bindsym $mod+End exec /a/opt/clipster/clipster -sp
+bindsym $mod+End $ex /a/opt/clipster/clipster -sp
 
-# file:///usr/share/doc/i3-wm/userguide.html#_border_style_for_new_windows
-new_window none
+# title bars but no borders. i tried this out a bit
+#default_border normal 0
+default_border pixel 4
 
 # I dont see a way to make processing windows act like normal windows,
 # this does it.
@@ -148,3 +191,7 @@ new_window none
 
 # this is the processing window for my app named focus.
 for_window [class="focus" instance="focus"] floating disable
+
+client.focused          #4c7899 #285577 #ffffff #2e9ef4   #ff4400
+client.focused_inactive #333333 #5f676a #ffffff #484e50   #DBEEF4
+client.unfocused        #333333 #222222 #888888 #292d2e   #B8C8CD
index c94b51b68644491f54ed89990e8788c64e8c1bc6..aefcee869ff276ed22fb091bf626f02483abfbd9 100644 (file)
@@ -5,6 +5,12 @@ bindsym $mod+Shift+p restart
 
 # need this for kde connect
 bar {
+
+# keep it only on secondary monitor to save space and make for less
+# missing pixes in obs live stream. For docs on this, search "output
+# primary" in the i3 guide.
+output primary
+
 # the builtin prog
 #status_command i3status
 
@@ -18,10 +24,8 @@ font pango:monospace 18
 # i have no need for the tray icons so far
 tray_output primary
 
-# this display is interesting, but I don't use it.
-# if I forget which workspace I'm in, I just tend to
-# toggle between all of them.
-workspace_buttons no
+# I found I didn't need these, but, I'm trying them out again.
+# workspace_buttons no
 }
 
 ## dont want to see this bar for now
@@ -31,6 +35,7 @@ workspace_buttons no
 # workspace_buttons no
 # }
 
-exec copyq
-exec dunst
-exec /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd
+$ex copyq
+$ex dunst
+$ex /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd
+$ex /a/opt/i3-alternating-layout/alternating_layouts.py
diff --git a/iboot b/iboot
index bc84f6ca7be1b5874472c204f1abfd49e8d01bbd..96ccdb227b0d4d7910bfbd7ee8b348aa459759ca 100644 (file)
--- a/iboot
+++ b/iboot
@@ -1,8 +1,7 @@
 #!/bin/bash
 
 ## in development, meant to be run manually
-
-[[ $EUID == 0 ]] || exec sudo -E "$script" "$@"
+[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
 
 if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
 shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
@@ -11,8 +10,8 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${P
 
 set -x
 
-d=(/dev/mapper/crypt_dev*)
-d=${d[0]}
+da=(/dev/mapper/crypt_dev*)
+d=${da[0]}
 
 mount -o subvol=root_trisquelnabia $d /mnt
 
@@ -24,6 +23,6 @@ mount -o bind /dev dev
 mount -o bind /proc proc
 mount -o bind /sys sys
 mkdir -p boot/efi
-mount $(awk '$2 == "/boot/efi" {print $1}' /etc/mtab) boot/efi
+mount "$(awk '$2 == "/boot/efi" {print $1}' /etc/mtab)" boot/efi
 chroot .
 # then run zboot-chroot
diff --git a/ic-tmp-setup b/ic-tmp-setup
new file mode 100755 (executable)
index 0000000..7ed1d9b
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+mkdir -p /t/ic
+chown icecast2:iank /t/ic
+chmod 775 /t/ic
index 8085d074feb85b49ff72025c26081c62033055ba..46520b949b91720d21bbe29a9f3e52cbe15e994f 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
+# shellcheck source=/a/bin/ds/.bashrc
 if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi
 set -x
 # Copyright (C) 2016 Ian Kelling
@@ -90,11 +91,11 @@ if set_device_id "Logitech Unifying Device"; then
   xinput --set-prop "$device_id" 'Evdev Middle Button Emulation' 1
 fi
 
-# slow down ploopy trackball, until we recompile firmware
-id=$(xinput list | grep -F 'Ploopy Corporation Trackball Mouse' | sed -rn 's/.*[[:space:]]id=([^[:space:]]*).*/\1/p' ||:)
-if [[ $id ]]; then
-  xinput --set-prop $id  'libinput Accel Speed' -0.9
-fi
+## slow down ploopy trackball, until we recompile firmware
+id=$(xinput list | grep -F 'Ploopy Corporation Trackball Mouse' | sed -rn 's/.*[[:space:]]id=([^[:space:]]*).*/\1/p' ||:)
+if [[ $id ]]; then
+  xinput --set-prop $id  'libinput Accel Speed' -0.9
+fi
 
 set +x
 exit 0
index 92ea7a6faf1d1642a61ee9c804258865c1dfb9d2..276b83917486bf1332e75cc625b24b3cb281160e 100755 (executable)
@@ -1,2 +1,2 @@
 #!/bin/bash
-nsenter -t $(systemctl show --property MainPID --value mailnn) -n -m ip6tables "$@"
+nsenter -t "$(systemctl show --property MainPID --value mailnn)" -n -m ip6tables "$@"
index b35a3446fae660e87314d86102cc2ac7678af452..1b87af13fb028b49b84ad6c764a78f7ef1427cd3 100755 (executable)
@@ -1,2 +1,2 @@
 #!/bin/bash
-nsenter -t $(systemctl show --property MainPID --value mailnn) -n -m iptables "$@"
+nsenter -t "$(systemctl show --property MainPID --value mailnn)" -n -m iptables "$@"
index 8f66f7c4c8e499787d64f758c4da10f9572469a1..98d15486a3af5752d3ae09eb2b7c0279b50a984f 100755 (executable)
@@ -14,7 +14,6 @@ if [[ $- != *i* ]]; then
   exec &>>/var/log/keyscript-on.log
   echo "$0: starting. $(date)"
 fi
-rootn=1
 
 sed="sed --follow-symlinks"
 
@@ -32,7 +31,7 @@ if [[ $INVOCATION_ID ]]; then
     # exists when /a is unmounted.
     source /dev/shm/iank-status
   fi
-  if [[ $MAIL_HOST && $MAIL_HOST != $HOSTNAME ]]; then
+  if [[ $MAIL_HOST && $MAIL_HOST != "$HOSTNAME" ]]; then
     echo "$0: exiting early: running under systemd as MAIL_HOST"
     exit 0
   fi
index 99563a98ad4a61b12c19b7b33545a07554c33789..4202ccbd053926dd8b96521d1b9629e6f1829760 100755 (executable)
@@ -13,12 +13,12 @@ esac
 
 f=/a/bin/bash_unpublished/source-state
 if [[ -e $f ]]; then
+  # shellcheck source=/a/bin/bash_unpublished/source-state
   source $f
 fi
 
 case $HOSTNAME in
   $MAIL_HOST|bk)
-    local_mx=mail.iankelling.org
     # ||: is to allow for temporary connection issues.
     rsync "${opt[@]}" -ogtL --chown=root:Debian-exim --chmod=640 \
           root@li.iankelling.org:/etc/letsencrypt/live/mail.iankelling.org/{fullchain.pem,privkey.pem} /etc/exim4 ||:
index 04ac198a0a514f49d316cf92e82e5cc8fe95007a..3da3abf5fa3df9ee158c8faf9c7715d74032d3ec 100755 (executable)
@@ -18,7 +18,8 @@
 
 set -e; . /usr/local/lib/bash-bear; set +e
 
-script_dir=$(dirname $(readlink -f "$BASH_SOURCE"))
+readonly this_file; this_file="$(readlink -f -- "${BASH_SOURCE[0]}")";
+script_dir=${this_file%/*}
 
 if (( ! $# )); then
   echo "mount-latest-remote: error: a host argument"
@@ -49,7 +50,7 @@ if [[ $tg == *:* ]]; then
   rsynctg="[$tg]"
 fi
 # R = relative, t = times, O = omit-dir-times, p = perms
-er rsync -RtOp bin/{mount-latest-subvol,check-subvol-stale} lib/bash-bear "root@$rsynctg:/usr/local" || continue
+er rsync -RtOp bin/{mount-latest-subvol,check-subvol-stale} lib/bash-bear "root@$rsynctg:/usr/local" ||:
 # note: this can hang if we have an old nfs mount.
 er ssh root@$tg timeout -s 9 600 /usr/local/bin/mount-latest-subvol "$@"
 
index dfe65db1f1d15be994c9dc995b83d0d9ee3177bb..af6385e9ab36396c77f6baf6fc26285ef59cdf7b 100644 (file)
@@ -241,8 +241,8 @@ shopt -s nullglob
 fa=(/mnt/root/btrbk/q.*); f=${fa[0]}
 if [[ -e $f ]]; then
   fstab <<EOF
-$crypt_dev  /q  btrfs  noatime,subvol=q,gid=1000$mopts  0 0
-$crypt_dev  /qd  btrfs  noatime,subvol=qd,gid=1000$mopts  0 0
+$crypt_dev  /q  btrfs  noatime,subvol=q$mopts  0 0
+$crypt_dev  /qd  btrfs  noatime,subvol=qd$mopts  0 0
 /q/p  /p  none  bind$mopts  0 0
 EOF
 fi
@@ -258,7 +258,7 @@ fi
 # fa=(/mnt/root/btrbk/ar.*); f=${fa[0]}
 # if [[ -e $f ]]; then
 #   fstab <<EOF
-# $crypt_dev  /ar  btrfs  noatime,subvol=ar,uid=1000,gid=1000$mopts  0 0
+# $crypt_dev  /ar  btrfs  noatime,subvol=ar,uid=1000$mopts  0 0
 # EOF
 # fi
 
index f97b5985da7f3583fc98dc85d5793dd056845005..eeb370db2a7e2aa204b90b33f80a5f16fb55d6ce 100755 (executable)
@@ -12,7 +12,7 @@ for dir in $(emacs --batch --eval '(progn(package-initialize) (dolist (x Info-di
     # this is from /usr/sbin/update-info-dir
     */info)
 
-      find $dir -type f | while read file ; do
+      find $dir -type f | while read -r file ; do
         case $file in
           */dir|*/dir.gz|*/dir.old|*/dir.old.gz|*-[0-9]|*-[0-9].gz|*-[1-9][0-9]|*-[1-9][0-9].gz|*.png|*.jpg)
             # these files are ignored
@@ -28,7 +28,7 @@ for dir in $(emacs --batch --eval '(progn(package-initialize) (dolist (x Info-di
     # ignore relative
     [^/]*) : ;;
     *)
-      for file in $dir/*.info*; do
+      for file in "$dir"/*.info*; do
         echo $file
         sudo install-info "$file" "$INFODIR/dir"
       done
index 7183a8ff7eec6360277ed807bfad2befc7925ca4..fbeeabddf12d1b8a299c3b097573cbaed8d1758f 100755 (executable)
@@ -155,6 +155,13 @@ main() {
     ps_char="=======FOCUS====== $ps_char"
   fi
 
+  if [[ -e /tmp/iank-i3-no-auto ]]; then
+    ps_char="$ps_char I"
+  fi
+  if [[ -e /tmp/no-obs-auto-scene-switch ]]; then
+    ps_char="$ps_char O"
+  fi
+
 
   printf '{ "name":"status", "color":"#ED297D", "full_text": "%s' "$ps_char"
   printf '"},'
index 5affcd4640a4471dd0d050406def8cd0e50a6023..3026af75d46586ae31951db02a9a75d6dadbe767 100755 (executable)
@@ -21,6 +21,7 @@ i() { # install file
   tmp=$(rsync -ic $tmpdir/"$base" "$dest")
   if [[ $tmp ]]; then
     printf "%s\n" "$tmp"
+    # shellcheck disable=SC2034
     ir=true
     if [[ $dest == /etc/systemd/system/* ]]; then
       touch /var/local/mail-setup-reload
diff --git a/obs b/obs
new file mode 100755 (executable)
index 0000000..bff119b
--- /dev/null
+++ b/obs
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+
+
+obs-i3-monitor &
+
+#/usr/bin/sleep 1234 &
+
+# https://obsproject.com/forum/threads/please-safe-mode-or-normal-mode-alert-function-on-off-toggle-add-to-setting.171047/
+/usr/bin/obs --disable-shutdown-check "$@" ||:
+
+kill %%
diff --git a/obs-auto-scene-switch-toggle b/obs-auto-scene-switch-toggle
new file mode 100755 (executable)
index 0000000..cc067b1
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+
+# the last select is so jq -e will tell us when it isn't found, which is
+# a bit cooler than doing an output comparison... maybe? I'm not sure
+if i3-msg -t get_tree | jq -e '.. | select(.focused? == true) | select(.floating == "user_on")' &>/dev/null; then
+  exit 0
+fi
+
+f=/tmp/no-obs-auto-scene-switch
+
+if [[ -e $f ]]; then
+  rm -f $f
+else
+  touch $f
+fi
diff --git a/obs-i3-interlude b/obs-i3-interlude
new file mode 100755 (executable)
index 0000000..303dec1
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -e; . /usr/local/lib/bash-bear; set +e
+
+if [[ -e /tmp/no-obs-auto-scene-switch ]]; then
+  rm -f /tmp/no-obs-auto-scene-switch
+  if [[ -s /tmp/last-obs-i3-mark ]]; then
+    p=$(cat /p/obs-ws-pass)
+    mark=$(cat /tmp/last-obs-i3-mark)
+    obs-cmd -w obsws://localhost:4455/$p scene switch $mark
+  fi
+else
+  touch /tmp/no-obs-auto-scene-switch
+  obs-cmd -w obsws://localhost:4455/$p scene switch interlude
+fi
diff --git a/obs-i3-monitor b/obs-i3-monitor
new file mode 100755 (executable)
index 0000000..26d17f8
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+set -e; . /usr/local/lib/bash-bear; set +e
+
+try() {
+  "$@" || printf "warning: failed %s\n" "$*"
+}
+
+while true; do
+  while read -r line ; do
+    mark=$(printf "%s\n" "$line" | jq -r 'select (.change == "focus") | .container.marks[0]') ||:
+    if [[ $mark && $mark != null ]]; then
+      echo $mark > /tmp/last-obs-i3-mark
+      if [[ ! -e /tmp/no-obs-auto-scene-switch ]]; then
+        p=$(cat /p/obs-ws-pass)
+        try obs-cmd -w obsws://localhost:4455/$p scene switch $mark
+      fi
+    fi
+    # debugging
+    #printf "%s\n" "$line" | jq
+
+
+    # intentional process substitution to properly exit on kill
+    # ||: avoids error messages
+  done < <(i3-msg -t subscribe -m '[ "window" ]' ||:)
+  sleep 5
+done
diff --git a/pkgs b/pkgs
index f318c4e4bff64672a3a9c965731f2429dee7cc78..345ce581b5525373b560585a8a325a0cff79b439 100644 (file)
--- a/pkgs
+++ b/pkgs
@@ -152,6 +152,7 @@ p3=(
   glibc-doc
   goaccess
   gnome-screenshot
+  # color picker
   gpick
   grepmail
   guvcview
@@ -283,6 +284,8 @@ p3=(
   xawtv
   xbacklight
   xdot
+  # needed for some i3 hacks
+  xdotool
   xloadimage
   xprintidle
   xscreensaver
index 182371ea5beaf82cc53427eec20935420094c3ed..42321c0598ed3615991dcd1c6d6441d2648e33de 100755 (executable)
@@ -5,13 +5,15 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
 [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
 
-for n in bullseye; do
-  if [[ -e /etc/schroot/chroot.d/$n.conf ]]; then
-    cd /
-    schroot -c $n -- apt-get -y update
-    schroot -c $n -- apt-get -y dist-upgrade --purge --auto-remove
-  fi
-done
+# used to have more than one, leaving commented in case we do
+#for n in bullseye; do
+n=bullseye
+if [[ -e /etc/schroot/chroot.d/$n.conf ]]; then
+  cd /
+  schroot -c $n -- apt-get -y update
+  schroot -c $n -- apt-get -y dist-upgrade --purge --auto-remove
+fi
+#done
 
 # if we haven't upgraded yet
 if [[ ! -d /mnt/boot/debianbullseye_bootstrap ]]; then
index 426d098c4e37eb972409b210ef627850fa2f2f71..4fcbc92098bd5cbc34b87e0d7fbc640170fb79f8 100755 (executable)
@@ -17,13 +17,14 @@ if [[ $EUID != 0 ]]; then
     sudo "$0"
     exit
 fi
+# shellcheck source=/a/bin/ds/.bashrc
 if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi
 
 
 set -eE -o pipefail
 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
 
-cd $(dirname $0)
+readonly this_file; this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"; cd ${this_file%/*}
 # get rid of useless motd stuff
 sed -i --follow-symlinks 's/^\s*PrintLastLog .*/PrintLastLog no/' /etc/ssh/sshd_config
 rm -f /etc/update-motd.d/10-help-text /etc/update-motd.d/00-header
index 56023b770142812c1f2f274274bd2e7b4f532f27..9af96a3f2b9709f8e1132556e4ffd914c5b0f163 100644 (file)
@@ -5,6 +5,7 @@
 loop-file=no
 volume=50
 player-operation-mode=pseudo-gui
+replaygain=track
 
 # use --profile d
 [d]
@@ -19,7 +20,7 @@ shuffle
 
 # audio, especially with beetag
 [a]
-volume=75
+volume=100
 player-operation-mode=cplayer
 audio-display=no
 # dont display any tags
index edfc30ac827e7a5ca78443c2c23a4ef44b77c792..ce1bc86abc5cb3259de218c88c6b5604af653dab 100644 (file)
@@ -347,7 +347,7 @@ if (( ret )); then
   bang="███████"
   e $bang failed btrbk of /o. restoring old host as primary
   if ! m $old_shell /a/exe/primary-setup localhost; then
-    die due to failed btrbk of /o, we tried to restore old host as primary, but then we failed at that too. To resolve: Fix & rerun switch-mail-host, or fix and rerun primary-setup localhost on old shell so you have a working mail server and then rerun switch-mail-host.
+    die "due to failed btrbk of /o, we tried to restore old host as primary, but then we failed at that too. To resolve: Fix & rerun switch-mail-host, or fix and rerun primary-setup localhost on old shell so you have a working mail server and then rerun switch-mail-host."
   fi
   e finished restoring old host as primary, now exiting $ret due to earlier failed btrbk of /o.
   exit $ret
index dd327bb0836979310df0476389df5d4971a106dc..f9b0eee9a964e715dbda918d1323e57fd1902791 100755 (executable)
@@ -390,17 +390,20 @@ write-status() {
   fi
 
   mprom=/var/lib/prometheus/node-exporter/mailtest-check.prom
-  if grep -qE 'mailtest_check_(unexpected|missing).*[^ ][^0]$' $mprom; then
-    chars+=("MTEST_SPAM")
-  fi
-  mtest_found=false
-  for t in $(grep -E ^mailtest_check_last_usec $mprom | awk '{print $NF}'); do
-    if (( t + 60 * 20 < EPOCHSECONDS )); then
-      mtest_found=true
+  if [[ -s $mprom ]]; then
+    if grep -qE 'mailtest_check_(unexpected|missing).*[^ ][^0]$' $mprom; then
+      chars+=("MTEST_SPAM")
+    fi
+    mtest_found=false
+    # shellcheck disable=SC2013 # these are words
+    for t in $(grep -E ^mailtest_check_last_usec $mprom | awk '{print $NF}'); do
+      if (( t + 60 * 20 < EPOCHSECONDS )); then
+        mtest_found=true
+      fi
+    done
+    if $mtest_found; then
+      chars+=("MTEST_AGE")
     fi
-  done
-  if $mtest_found; then
-    chars+=("MTEST_AGE")
   fi
 
   if [[ ! -e $status_file || -w $status_file ]]; then
index 825604e8421e21698b066860f0fb8dfe3807b471..755fb1f5239dd999f2388471ee6fe09e352eb25b 100755 (executable)
@@ -8,8 +8,6 @@
 
 source /a/bin/bash-bear-trap/bash-bear
 
-readonly this_file=$(readlink -f -- "${BASH_SOURCE[0]}")
-readonly this_dir="${this_file%/*}"
 script_name="${BASH_SOURCE[0]}"
 script_name="${script_name##*/}"
 
@@ -92,7 +90,7 @@ fi
 
 
 # wait for networkmanager to come back
-for f in {1..20}; do
+for ((i=0; i<10; i++)); do
   if read -r _ _ _ _  gateway_if _ < <(ip route get 8.8.8.8); then
     break
   fi
index f6ff1687cc706f580218822eb454c61fe1cbe8a4..9331d006bddd4657a296f281eca81565b9709a7a 100755 (executable)
@@ -9,7 +9,7 @@ ifname=$1
 shift
 
 # wait up to 10 seconds for the gateway to appear
-for i in in {1..10}; do
+for ((i=0; i<10; i++)); do
   gw=$(/usr/sbin/ip route | sed -rn 's/^default via .* dev (\S+).*/\1/p')
   if [[ $gw ]]; then
     found=true
index bef79330f453bc4992f3267cc6e779f38b16d29c..8ecce1c8ce83aba53fc381fbc74e56ad47dd149b 100755 (executable)
@@ -15,7 +15,7 @@ conf=$1
 main() {
   while read -r host port; do
     while read -r ip; do
-      echo $ip | egrep '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' &>/dev/null || continue
+      echo $ip | grep -E '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' &>/dev/null || continue
       printf "remote %s %s\n" "$ip" "$port" >>$conf
       ret=0
     done < <(timeout -s 9 1 dig +short $host ||:)
diff --git a/zboot b/zboot
index bf9c7c25a32b29c80ddf3317fa6d7c58913b1e53..082afb5b4e03f5cff318637a7b0e6c276823d13a 100755 (executable)
--- a/zboot
+++ b/zboot
@@ -1,7 +1,6 @@
 #!/bin/bash
 
-script=$(readlink -f -- "$BASH_SOURCE")
-[[ $EUID == 0 ]] || exec sudo -E "$script" "$@"
+[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
 
 set -e; . /usr/local/lib/bash-bear; set +e
 
@@ -33,7 +32,7 @@ mount -o bind /dev dev
 mount -o bind /proc proc
 mount -o bind /sys sys
 mkdir -p boot/efi
-mount $(awk '$2 == "/boot/efi" {print $1}' /etc/mtab) boot/efi
+mount "$(awk '$2 == "/boot/efi" {print $1}' /etc/mtab)" boot/efi
 
 cp /b/ds/zboot-chroot ./root
 
index 4411cc48c36c4bb944e358ed70b40d5f019e7bcb..0a682086d0c4b119c7e99bd2a7a8d88ad5e650b4 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-[[ $EUID == 0 ]] || exec sudo -E "$script" "$@"
+[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
 
 if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
 shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
index 5c2ed56d9b749d1b91b256fb5c50f7f579500d30..b646d21c5e8f2f45e4b420df14a333c4b5d97929 100755 (executable)
@@ -10,7 +10,7 @@ pre="${0##*/}:"
 err() { echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: $pre: $*" >&2; }
 
 ## begin check on syncthing
-if ! systemctl show --no-page syncthing@ziva | sed -n 's/^MainPID=//p' | egrep '^[0-9]+$' &>/dev/null; then
+if ! systemctl show --no-page syncthing@ziva | sed -n 's/^MainPID=//p' | grep -E '^[0-9]+$' &>/dev/null; then
   err no pid for syncthing@ziva. systemctl status:
   systemctl status syncthing@ziva
 fi
@@ -34,16 +34,16 @@ for prefix in root boot; do
     break
   fi
 
-  read last_snap_sec last_snap < <(
+  read -r last_snap_sec last_snap < <(
     for s in ${snaps[@]}; do
       f=${s##*/}
-      unix_time=$(date -d $(sed -r  's/(.{4})(..)(.{5})(..)(.*)/\1-\2-\3:\4:\5/' <<<${f#$vol.}) +%s)
+      unix_time=$(date -d "$(sed -r  's/(.{4})(..)(.{5})(..)(.*)/\1-\2-\3:\4:\5/' <<<${f#"$vol".})" +%s)
       printf "%s %s\n" $unix_time $s # part of the pipeline
     done | sort -r | head -n 1 ||:
   )
   if [[ ! $last_snap ]]; then
     # should not happen.
-    err "could not find latest snapshot for $svp among ${snaps[*]}"
+    err "could not find latest snapshot for $vol among ${snaps[*]}"
     exit 1
   fi
   if (( last_snap_sec < EPOCHSECONDS - age_limit_sec )); then
index 646ae91c73bda9af582f05898f3d1a1d8ede8020..ac875c07b1f05e5194c98361f70cef83b20cfb47 100755 (executable)
@@ -20,7 +20,7 @@ cd $dest_dir
 shopt -s nullglob
 jpgs=( 20*jpg )
 if (( ${#jpgs[@]} >= 1 )); then
-  # shellcheck disable=SC2048 # intentional
+  # shellcheck disable=SC2012 # this is much sorter than find|sort
   lastf=$(ls -1 20*jpg  | tail -n1)
 fi