document sl function
authorIan Kelling <ian@iankelling.org>
Tue, 4 Aug 2020 21:13:11 +0000 (17:13 -0400)
committerIan Kelling <ian@iankelling.org>
Tue, 4 Aug 2020 21:13:11 +0000 (17:13 -0400)
.bashrc
brc
brc2

diff --git a/.bashrc b/.bashrc
index 04df859f14367be83d2655d2f12e9aee32c2b820..7a61595ab91366a8eb5535917bf6775bc35a50d9 100644 (file)
--- a/.bashrc
+++ b/.bashrc
 
 
 
-# History related options first, or else
-# we risk screwing up history history. And this is duplicated
-# in ~/.bash_profile just for good measure
-# history number. History expansion is good.
-PS4='$LINENO+ '
-# history file size limit, set to unlimited.
+# History related options first and always, or else we risk screwing up
+# the history file. This is duplicated in ~/.bash_profile just for good
+# measure
+
+# History file size limit, set to unlimited.
 # this needs to be different from the default because
 # default HISTFILESIZE is 500 and could clobber our history
 HISTFILESIZE=
@@ -27,15 +26,19 @@ HISTSIZE=1000000
 HISTTIMEFORMAT="%Y-%m-%d %I:%M %p "
 # consecutive duplicate lines dont go in history
 HISTCONTROL=ignoredups
-# works in addition to HISTCONTROL to do more flexible things
+# This works in addition to HISTCONTROL to do more flexible things
 # it could also do the same things as HISTCONTROL and thus replace it,
 # but meh. dunno why, but just " *" does glob expansion, so use [ ] to avoid it.
 HISTIGNORE='pass *:[ ]*:otp *:oathtool *'
 
 
-# see comments in brc2 sl() function for background.
+#### begin section that works with sl() function to return from
+#### noninteractive ssh shells
 if [[ $SSH_CONNECTION ]] \
      && [[ $BRC != t ]];  then
+  # Here we did not opt-in to running our .bashrc file so we just
+  # return, but we still setup a function to source it without returning
+  # so if we want it we don't have to restart our ssh connection.
   brc() {
     export BRC=t
     source ~/.bashrc
@@ -43,8 +46,10 @@ if [[ $SSH_CONNECTION ]] \
   return 0
 else
 
-  # the distinction between login and non-login shells is lame,
-  # get rid of it. note ssh shells normally its login if a command is passed
+  ###### Begin sourcing of files #####
+
+  # The distinction between login and non-login shells is super lame
+  # and pretty random. get rid of that distinction.
   if ! shopt -q login_shell; then
     if [[ -r /etc/profile ]]; then
       source /etc/profile
@@ -54,6 +59,9 @@ else
     # this file, and we don't want to do that and cause an infinite
     # loop.
   fi
+
+  # source brc and brc2 if they exist. We have to readlink because we
+  # could be using sl() from ./brc.
   _tmp=$(readlink -f ${BASH_SOURCE[0]})
   _tmp=${_tmp%/*}
   _tmp2=$_tmp/brc
@@ -75,7 +83,10 @@ else
       source $_tmp2
     fi
   fi
+  ###### End sourcing of files #####
 fi
+#### end section that works with sl() function to return from
+#### noninteractive ssh shells
 
 
 # ensure no bad programs appending to this file will have an affect
diff --git a/brc b/brc
index f00310c2fe6d230e68590d8b726d5369b6d72428..01c151a1623caa555f3f2cd7a12280bfe5698e96 100644 (file)
--- a/brc
+++ b/brc
@@ -49,6 +49,10 @@ shopt -s extglob
 # setting this also sets dotglob.
 export GLOBIGNORE="*/.:*/.."
 
+# Useful info. see man bash.
+PS4='$LINENO+ '
+
+
 # broken with bash_completion package. Saw a bug for this once. dont anymore.
 # still broken in wheezy
 # still buggered in latest stable from the web, version 2.1
@@ -181,6 +185,10 @@ export SYSTEMD_LESS=$LESS
 
 export NNN_COLORS=2136
 
+export SL_FILES_DIR=/b/ds/sl/.iank
+export SL_INFO_DIR=/p/sshinfo
+
+
 # * include files
 
 
@@ -1079,6 +1087,194 @@ sk() {
 }
 
 
+# sl: ssh, but firsh rsync our bashrc and related files to a special
+# directory on the remote host if needed.
+
+# Some environment variables and files need to be setup for this to work
+# (mine are set at the beginning of this file)
+
+# SL_FILES_DIR: Environment variable. Path to folder which should at
+# least have a .bashrc file or symlink. This dir will be rsynced to
+# remote hosts unless the host already has a $SL_FILES_DIR/.bashrc. In
+# that case, we assume it is a host you control and sync files to
+# separately and already has the ~/.bashrc you want.  Symlinks in this
+# dir will be resolved. The directory name is important, it will be
+# created on the remote host under /root. The remote bash will also take
+# its .inputrc config from this folder (default of not existing is
+# fine). Mine looks like this:
+# https://iankelling.org/git/?p=distro-setup;a=tree;f=sl/.iank
+
+# SL_INFO_DIR: Environment variable. This folder stores info about what
+# we detected on the remote system and when we last synced. We expect it
+# to exist ahead of time. Sometimes you may want to forget about a
+# remote system, you can use sl --rsync, or the function for that slr
+# below.
+
+# For when ~/.bashrc is already customized on the remote server, you
+# might find it problematic that ~/.bashrc is sourced for ALL ssh
+# commands, even in scripts. This paragraph is all about that. bash
+# scripts dont source ~/.bashrc, but call ssh in scripts and you get
+# ~/.bashrc. You dont want this. .bashrc is meant for interactive shells
+# and if you customize it, probably has bugs from time to time. This is
+# bad. Here's how I fix it. I have a special condition to "return" in my
+# .bashrc for noninteractive ssh shells (you can copy this).  To make
+# this work, you need to alter AcceptEnv in /etc/ssh/sshd_config, adding
+# the var BRC to it. And in ~/.ssh/config or equivalent, add SendEnv
+# BRC, plus any other environment vars you want to send. This function
+# uses the BRC environment variable to enable that. Also, I don't keep
+# most of my bashrc in .bashrc, because even though I return, the whole
+# file gets parsed which can fail if there is a syntax error (plus,
+# faster bash startup when we are just going to return).
+#
+sl() {
+  # Background on BRC var (no need to read if you just want to use this
+  # function): bash builtin vars and env show no difference in ssh vs
+  # local, except shell level which is not reliable. only reliable way I
+  # found was env var. env variables sent across ssh are strictly
+  # limited. We could override an obscure unused LC_var, like telephone,
+  # but I don't want to run into some edge case where that messes things
+  # up. Note, on hosts we dont control I start an inner shell with BRC
+  # set, and the inner shell also allows running a nondefault
+  # .bashrc. This means the outer shell still ran the default .bashrc,
+  # but that is the best we can do.
+
+  local now args remote dorsync haveinfo tmpa sshinfo tmp tmp2 type info_sec force_rsync sync_dirname
+  declare -a args tmpa
+
+  sync_dirname=${SL_FILES_DIR##*/}
+
+  now=$(date +%s)
+
+  # ssh [-1246Antivivisectionist] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
+  # [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L address]
+  # [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option]
+  # [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname
+  # [command]
+
+  # ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
+  # [-D [bind_address:]port] [-E log_file] [-e escape_char]
+  # [-F configfile] [-I pkcs11] [-i identity_file]
+  # [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]
+  # [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]
+  # [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
+
+  force_rsync=false
+  if [[ $1 == --rsync ]]; then
+    force_rsync=true
+    shift
+  fi
+
+  while [[ $1 ]]; do
+    case "$1" in
+      # note we dont support things like -4oOption
+      -[46AaCfGgKkMNnqsTtVvXxYy]*)
+        args+=("$1"); shift
+        ;;
+      -[bcDEeFIiJLlmOopQRSWw]*)
+        # -oOption etc is valid
+        if (( ${#1} >= 3 )); then
+          args+=("$1"); shift
+        else
+          args+=("$1" "$2"); shift 2
+        fi
+        ;;
+      *)
+        break
+        ;;
+    esac
+  done
+  remote="$1"; shift
+  if [[ ! $remote ]]; then
+    echo $0: error hostname required >&2
+    return 1
+  fi
+
+  dorsync=false
+  haveinfo=false
+  tmpa=($SL_INFO_DIR/???????????"$remote")
+  sshinfo=${tmpa[0]}
+  if [[ -e $sshinfo ]]; then
+    if $force_rsync; then
+      rm -f $sshinfo
+    else
+      haveinfo=true
+    fi
+  fi
+  if $haveinfo; then
+    tmp=${sshinfo[0]##*/}
+    tmp2=${tmp::11}
+    type=${tmp2: -1}
+    if [[ $type == b ]]; then
+      info_sec=${tmp::10}
+      for f in $SL_FILES_DIR/*; do
+        if (( $(stat -L -c%Y $f) > info_sec )); then
+          dorsync=true
+          rm -f $sshinfo
+          break
+        fi
+      done
+    fi
+  else
+    # use this weird yes thing to ensure we know ssh succeeded
+    if ! tmp=$(command ssh "${args[@]}" "$remote" "if test -e $SL_FILES_DIR/.bashrc -a -L .bashrc; then echo yes; fi"); then
+      echo failed sl test. doing plain ssh -v
+      command ssh -v "${args[@]}" "$remote"
+    fi
+    if [[ $tmp == yes ]]; then
+      type=a
+    else
+      dorsync=true
+      type=b
+    fi
+  fi
+  if $dorsync; then
+    RSYNC_RSH="ssh ${args[*]}" rsync -rptL $SL_FILES_DIR "$remote":
+  fi
+  if $dorsync || ! $haveinfo; then
+    sshinfo=$SL_INFO_DIR/$now$type"$remote"
+    touch $sshinfo
+    chmod 666 $sshinfo
+  fi
+  if [[ $type == b ]]; then
+    if (( ${#@} )); then
+      # Theres a couple ways to pass arguments, im not sure whats best,
+      # but relying on bash 4.4+ escape quoting seems most reliable.
+      command ssh "${args[@]}" "$remote" \
+              BRC=t bash -c '.\ '$sync_dirname'/.bashrc\;"\"\$@\""' bash ${@@Q}
+    elif [[ ! -t 0 ]]; then
+      # This case is when commands are being piped to ssh.
+      # Normally, no bashrc gets sourced.
+      # But, since we are doing all this, lets source it because we can.
+      cat <(echo . $sync_dirname/.bashrc) - | command ssh "${args[@]}" "$remote" BRC=t bash
+    else
+      command ssh -t "${args[@]}" "$remote" BRC=t INPUTRC=$sync_dirname/.inputrc bash --rcfile $sync_dirname/.bashrc
+    fi
+  else
+    if [[ -t 0 ]]; then
+      BRC=t command ssh "${args[@]}" "$remote" ${@@Q}
+    else
+      command ssh "${args[@]}" "$remote" BRC=t bash
+    fi
+  fi
+  # this function inspired from https://github.com/Russell91/sshrc
+}
+slr() {
+  sl --rsync "$@"
+}
+sss() { # ssh solo
+  sl -oControlMaster=no -oControlPath=/ "$@"
+}
+# kill off old shared socket then ssh
+ssk() {
+  m ssh -O exit "$@" || [[ $? == 255 ]]
+  m sl "$@"
+}
+# plain ssh
+ssh() {
+  BRC=t command ssh "$@"
+}
+
+
 slog() {
   # log with script. timing is $1.t and script is $1.s
   # -l to save to ~/typescripts/
diff --git a/brc2 b/brc2
index 8da9bbf63b7ebdbd2dbe034b3d818a569f5b8ae2..be1aca165f6818aee41b4108fbc2108c1e3d9898 100644 (file)
--- a/brc2
+++ b/brc2
@@ -22,6 +22,7 @@ path-add --ifexists --end /a/opt/scancode-toolkit-3.10.
 export WCDHOME=/a
 
 
+
 # * include files
 
 # generated instead of dynamic for the benefit of shellcheck
@@ -1023,179 +1024,6 @@ spend() {
   sudo systemctl suspend
 }
 
-# ssh, copy my universal config over if needed.
-
-# By default .bashrc is sourced for ALL ssh commands. This is wonky.
-# Normally, this file is not sourced when a script is run, but we can
-# override that by sourcing ~/.bashrc.  I want the same thing for ssh
-# commands. when a local script runs an ssh command, bashrc should not be
-# sourced, unless we use a modified command.
-#
-# So, in my bashrc, test for conditions of noninteractive ssh and return
-# if so.  And we don't keep the rest of the code in .bashrc, because
-# even though we return, we parse the whole file which can cause errors
-# as we develop it.
-#
-# To test for an overriding condition: bash builtin vars and env show no
-# difference in ssh vs local, except shell level which is not
-# reliable. one option is to use an environment variable. env variables
-# sent across ssh are strictly limited. We could override an obscure
-# unused LC_var, like telephone, but I don't want to run into some edge
-# case where that messes things up. I choose to set SendEnv and
-# AcceptEnv ssh config vars to allow the environment variable BRC to
-# propagate across ssh, and for hosts I don't control, I start an inner
-# shell with it set, which doubles up as a way to have a nondefault
-# bashrc.
-sl() {
-  # inspired from https://github.com/Russell91/sshrc
-
-
-  local now args remote dorsync haveinfo tmpa sshinfo tmp tmp2 type info_sec force_rsync \
-        sshinfo_dir sync_files_dir sync_files_dir
-  declare -a args tmpa
-  # This folder stores info about what we detected or synced. We expect it to exist
-  # ahead of time. Change it for your own system.
-  sshinfo_dir=/p/sshinfo
-
-  # This folder should contain files or symlinks to all files that
-  # should be rsynced to unknown hosts. The directory name is important,
-  # it will be created on the remote host under /root. symlinks will be
-  # resolved. It is expected to contain at least a .bashrc file or
-  # symlink.
-  sync_files_dir=/b/ds/sl/.iank
-  sync_dirname=${sync_files_dir##*/}
-
-  now=$(date +%s)
-
-  # ssh [-1246Antivivisectionist] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
-  # [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L address]
-  # [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option]
-  # [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname
-  # [command]
-
-  # ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
-  # [-D [bind_address:]port] [-E log_file] [-e escape_char]
-  # [-F configfile] [-I pkcs11] [-i identity_file]
-  # [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]
-  # [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]
-  # [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
-
-  force_rsync=false
-  if [[ $1 == --rsync ]]; then
-    force_rsync=true
-    shift
-  fi
-
-  while [[ $1 ]]; do
-    case "$1" in
-      # note we dont support things like -4oOption
-      -[46AaCfGgKkMNnqsTtVvXxYy]*)
-        args+=("$1"); shift
-        ;;
-      -[bcDEeFIiJLlmOopQRSWw]*)
-        # -oOption etc is valid
-        if (( ${#1} >= 3 )); then
-          args+=("$1"); shift
-        else
-          args+=("$1" "$2"); shift 2
-        fi
-        ;;
-      *)
-        break
-        ;;
-    esac
-  done
-  remote="$1"; shift
-  if [[ ! $remote ]]; then
-    echo $0: error hostname required >&2
-    return 1
-  fi
-  dorsync=false
-  haveinfo=false
-
-  tmpa=($sshinfo_dir/???????????"$remote")
-  sshinfo=${tmpa[0]}
-  if [[ -e $sshinfo ]]; then
-    if $force_rsync; then
-      rm -f $sshinfo
-    else
-      haveinfo=true
-    fi
-  fi
-  if $haveinfo; then
-    tmp=${sshinfo[0]##*/}
-    tmp2=${tmp::11}
-    type=${tmp2: -1}
-    if [[ $type == b ]]; then
-      info_sec=${tmp::10}
-      for f in $sync_files_dir/*; do
-        if (( $(stat -L -c%Y $f) > info_sec )); then
-          dorsync=true
-          rm -f $sshinfo
-          break
-        fi
-      done
-    fi
-  else
-    # use this weird yes thing to ensure we know ssh succeeded
-    if ! tmp=$(command ssh "${args[@]}" "$remote" "if test -e $sync_files_dir/.bashrc -a -L .bashrc; then echo yes; fi"); then
-      echo failed sl test. doing plain ssh -v
-      command ssh -v "${args[@]}" "$remote"
-    fi
-    if [[ $tmp == yes ]]; then
-      type=a
-    else
-      dorsync=true
-      type=b
-    fi
-  fi
-  if $dorsync; then
-    RSYNC_RSH="ssh ${args[*]}" rsync -rptL $sync_files_dir "$remote":
-  fi
-  if $dorsync || ! $haveinfo; then
-    sshinfo=$sshinfo_dir/$now$type"$remote"
-    touch $sshinfo
-    chmod 666 $sshinfo
-  fi
-  if [[ $type == b ]]; then
-    if (( ${#@} )); then
-
-      # Theres a couple ways to do this. im not sure whats best,
-      # but relying on bash 4.4+ escape quoting seems most reliable.
-      command ssh "${args[@]}" "$remote" \
-              BRC=t bash -c '.\ '$sync_dirname'/.bashrc\;"\"\$@\""' bash ${@@Q}
-    elif [[ ! -t 0 ]]; then
-      # This case is when commands are being piped to ssh.
-      # Normally, no bashrc gets sourced.
-      # But, since we are doing all this, lets source it because we can.
-      cat <(echo . $sync_dirname/.bashrc) - | command ssh "${args[@]}" "$remote" BRC=t bash
-    else
-      command ssh -t "${args[@]}" "$remote" BRC=t INPUTRC=$sync_dirname/.inputrc bash --rcfile $sync_dirname/.bashrc
-    fi
-  else
-    if [[ -t 0 ]]; then
-      BRC=t command ssh "${args[@]}" "$remote" ${@@Q}
-    else
-      command ssh "${args[@]}" "$remote" BRC=t bash
-    fi
-  fi
-}
-slr() {
-  sl --rsync "$@"
-}
-sss() { # ssh solo
-  sl -oControlMaster=no -oControlPath=/ "$@"
-}
-# kill off old shared socket then ssh
-ssk() {
-  m ssh -O exit "$@" || [[ $? == 255 ]]
-  m sl "$@"
-}
-# plain limited ssh
-ssh() {
-  BRC=t command ssh "$@"
-}
-
 
 # mail related
 testmail() {