small cleanup
[distro-setup] / .bashrc
diff --git a/.bashrc b/.bashrc
index b906d2e5b8560b476f646a1012e481d9554d90e3..3dc94d42688bc01d40cbb2a3f6fb9c9de4fbc8b5 100644 (file)
--- a/.bashrc
+++ b/.bashrc
@@ -1,3 +1,17 @@
+# Copyright (C) 2016 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # to debug
 #set -x
 # redirect output to log file. this doesn't work. todo figure out why
@@ -110,6 +124,28 @@ if [[ $INSIDE_EMACS ]]; then
     # scp completion does not work, but this doesn't fix it. todo, figure this out
     complete -r scp &> /dev/null
     # todo, remote file completion fails, figure out how to turn it off
+    export NODE_DISABLE_COLORS=1
+    # This get's rid of ugly terminal escape chars in node repl
+    # sometime, I'd like to have completion working in emacs shell for node
+    # the offending chars can be found in lib/readline.js,
+    # things that do like:
+    # stream.write('\x1b[' + (x + 1) + 'G');
+    # We can remove them and keep readline, for example by doing this
+    # to start a repl:
+    #!/usr/bin/env nodejs
+    # var readline = require('readline');
+    # readline.cursorTo = function(a,b,c) {};
+    # readline.clearScreenDown = function(a) {};
+    # const repl = require('repl');
+    # var replServer = repl.start('');
+    #
+    # no prompt, or else readline complete seems to be confused, based
+    # on our column being different? node probably needs to send
+    # different kind of escape sequence that is not ugly. Anyways,
+    # completion doesn't work yet even with the ugly prompt, so whatever
+    #
+    export NODE_NO_READLINE=1
+
 fi
 
 
@@ -174,7 +210,7 @@ C_DEFAULT_DIR=/a
 ## include files ###
 ###################
 
-for _x in /a/bin/distro-functions/src/* /a/bin/*/*-function; do
+for _x in /a/bin/distro-functions/src/* /a/bin/*/*-function?(s); do
     source "$_x"
 done
 unset _x
@@ -182,6 +218,7 @@ unset _x
 for x in /a/bin/bash_unpublished/*; do source $x; done
 source $(dirname $(readlink -f $BASH_SOURCE))/path_add-function
 source /a/bin/log-quiet/logq-function
+source /a/bin/log-quiet/log-once-function
 path_add /a/exe
 path_add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-tools
 # todo, these need to be renamed to be less generic.
@@ -229,13 +266,6 @@ unalias ls ll grep &>/dev/null ||:
 #####################
 
 
-mkdir() { command mkdir -p "$@"; }
-
-
-# fast commit all
-ic() {
-    git commit -am "$*"
-}
 
 
 # file cut copy and paste, like the text buffers :)
@@ -258,37 +288,10 @@ fpst() { # file paste
     cp "$my_f_tempdir"/* "$target"
 }
 
-# history search
-k() { grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history}  | tail -n 40; }
-
-# horizontal row. used to break up output
-hr() { printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq $COLUMNS); }
-
-
-# insensitive find
-ifn () {
-    find -L . -iname "*$**" 2>/dev/null
-}
-
-# test existence / exists
-te() {
-    local ret=0
-    for x in "$@"; do
-        [[ -e "$x" || -L "$x" ]] || ret=1
-    done
-    return $ret
-}
 
 # todo, update this
 complete -F _longopt la lower low rlt rld rl lld ts ll dircp ex fcp fct fpst gr
 
-# use sb instead of s is for sudo redirections, eg. sb 'echo "ok fine" > /etc/file'
-sb() {
-    local SUDOD="$PWD"
-    sudo -i bash -c "$@"
-}
-complete -F _root_command s sb
-
 
 _cdiff-prep() {
     # join options which are continued to multiples lines onto one line
@@ -313,9 +316,9 @@ _cdiff-prep() {
 
 _khfix_common() {
     local h=${1##*@}
-    ssh-keygen -R $h
+    ssh-keygen -R $h -f $(readlink -f ~/.ssh/known_hosts)
     local x=$(timeout 0.1 ssh -v $1 |& sed -rn "s/debug1: Connecting to $h \[([^\]*)].*/\1/p");
-    ssh-keygen -R $x
+    ssh-keygen -R $x -f $(readlink -f ~/.ssh/known_hosts)
 }
 khfix() { # known hosts fix
     _khfix_common "$@"
@@ -383,22 +386,28 @@ cdiff() {
     done < "$unified"
 }
 
-cgpl ()
+cgpl()
 {
-    if [[ $# == 0 ]]; then
+    if (($#)); then
+        cp /a/bin/data/COPYING "$@"
+    else
         cp /a/bin/data/COPYING .
+    fi
+}
+capache()
+{
+    if (($#)); then
+        cp /a/bin/data/LICENSE "$@"
     else
-        cp /a/bin/data/COPYING "$@"
+        cp /a/bin/data/LICENSE .
     fi
 }
-
 chown() {
     # makes it so chown -R symlink affects the symlink and its target.
     if [[ $1 == -R ]]; then
         shift
         command chown -h "$@"
-        command chown "$@"
-        command chown -RH "$@"
+        command chown -R "$@"
     else
         command chown "$@"
     fi
@@ -586,6 +595,30 @@ fw() {
     firefox -P default "$@" >/dev/null 2>&1
 }
 
+getdir () {
+    local help="Usage: getdir [--help] PATH
+Output the directory of PATH, or just PATH if it is a directory."
+    if [[ $1 == --help ]]; then
+        echo "$help"
+        return 0
+    fi
+    if [[ $# -ne 1 ]]; then
+        echo "getdir error: expected 1 argument, got $#"
+        return 1
+    fi
+    if [[ -d $1 ]]; then
+        echo "$1"
+    else
+        local dir="$(dirname "$1")"
+        if [[ -d $dir ]]; then
+            echo "$dir"
+        else
+            echo "getdir error: directory does not exist"
+            return 1
+        fi
+    fi
+}
+
 git_empty_branch() { # start an empty git branch. carefull, it deletes untracked files.
     [[ $# == 1 ]] || { echo 'need a branch name!'; return 1;}
     local gitroot
@@ -612,7 +645,6 @@ grr() {
     fi
 }
 
-
 hl() { # history limit. Write extra history to archive file.
     # todo: this is not working or not used currently
     local max_lines linecount tempfile prune_lines x
@@ -632,10 +664,16 @@ hl() { # history limit. Write extra history to archive file.
     if (($linecount > $max_lines)); then
         prune_lines=$(($linecount - $max_lines))
         head -n $prune_lines "$HISTFILE" >> "$harchive" \
-            && sed -ie "1,${prune_lines}d"  $HISTFILE
+            && sed --follow-symlinks -ie "1,${prune_lines}d"  $HISTFILE
     fi
 }
 
+hr() { # horizontal row. used to break up output
+    printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq $COLUMNS)
+    echo
+}
+
+
 i() { git "$@"; }
 # modified from ~/local/bin/git-completion.bash
 # other completion commands are mostly taken from bash_completion package
@@ -649,8 +687,17 @@ if ! type service &>/dev/null; then
     }
 fi
 
+ic() {
+    # fast commit all
+    git commit -am "$*"
+}
 
 
+ifn () {
+    # insensitive find
+    find -L . -iname "*$**" 2>/dev/null
+}
+
 
 if [[ $OS == Windows_NT ]]; then
     # cygstart wrapper
@@ -718,23 +765,29 @@ lower() { # make first letter of filenames lowercase.
     done
 }
 
-make-targets() {
-    # show make targets, via http://stackoverflow.com/questions/3063507/list-goals-targets-in-gnu-make
-    make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
+
+k() { # history search
+    grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history}  | tail -n 40;
 }
 
 
-md5diff() {
-    [[ $(md5sum < "$1") != $(md5sum < "$2") ]]
+make-targets() {
+    # show make targets, via http://stackoverflow.com/questions/3063507/list-goals-targets-in-gnu-make
+    make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
 }
 
 
-
 mkc() {
     mkdir "$1"
     c "$1"
 }
 
+mkdir() { command mkdir -p "$@"; }
+
+pithos() {
+    cd /a/opt/Pithosfly/
+    python3 -m pithos&r
+}
 
 pakaraoke() {
     # from http://askubuntu.com/questions/456021/remove-vocals-from-mp3-and-get-only-instrumentals
@@ -784,6 +837,10 @@ pub() {
     rld /a/h/_site/ li:/var/www/iankelling.org/html
 }
 
+pubip() { curl -4s https://icanhazip.com; }
+whatismyip() { pubip; }
+
+
 pwgen() {
     apg -s -m 10 -x 14 -t
 }
@@ -826,6 +883,7 @@ rlu() { # [OPTS] HOST PATH
     opts=("${@:1:$#-2}") #  1 to last -2
     path="${@:$#}" # last
     host="${@:$#-1:1}" # last -1
+    if [[ $path == .* ]]; then echo error: need absolut path; return 1; fi
     # rync here uses checksum instead of time so we don't mess with
     # unison relying on time as much. g is for group, same reason
     # to keep up with unison.
@@ -848,12 +906,8 @@ EOF
 
 s() {
     # background
-    # alias s='SUDOD="$PWD" sudo -i '
-    # because this is an alias, and the extra space at the end, it would allow
-    #  aliases to be used with it. but aliases aren't used in scripts,
-    #  better to eliminate inconsistencies. Plus, you can't do s=s; $s command
-    #  with an alias, which I like to do in some functions
-    # extra space at the end allows aliases to work
+    # I use a function because otherwise we can't use in a script,
+    # can't assign to variable.
     #
     # note: gksudo is recommended for X apps because it does not set the
     # home directory to the same, and thus apps writing to ~ fuck things up
@@ -879,9 +933,15 @@ safe_rename() {
     fi
 }
 
-sdf() {
-    c /sdx/test/sandbox/
+
+sb() { # sudo bash -c
+    # use sb instead of s is for sudo redirections,
+    # eg. sb 'echo "ok fine" > /etc/file'
+    local SUDOD="$PWD"
+    sudo -i bash -c "$@"
 }
+complete -F _root_command s sb
+
 
 ser() {
     local s; [[ $EUID != 0 ]] && s=sudo
@@ -950,6 +1010,11 @@ srm () {
     command srm -ll "$@"
 }
 
+srun() {
+    scp $2 $1:/tmp
+    ssh $1 /tmp/${2##*/} "${@:2}"
+}
+
 t() {
     local x
     local -a args
@@ -998,6 +1063,15 @@ tclock() {
 }
 
 
+te() {
+    # test existence / exists
+    local ret=0
+    for x in "$@"; do
+        [[ -e "$x" || -L "$x" ]] || ret=1
+    done
+    return $ret
+}
+
 tm() {
     # timer in minutes
     (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 &
@@ -1055,6 +1129,45 @@ tx() { # toggle set -x, and the prompt so it doesn't spam
     fi
 }
 
+vc() {
+    [[ $1 ]] || { e "$0: error, expected cmd to run"; return 1; }
+    # manually run vpn so it stays within a network namespace,
+    # until I get it all wired up with systemd.
+    newns vpn start
+    pid=$(< /run/openvpn/client.pid)
+    if [[ ! $pid ]]; then
+        s ip netns exec vpn /usr/sbin/openvpn --daemon ovpn --config /etc/openvpn/client.conf --cd /etc/openvpn --writepid /run/openvpn/client.pid
+    elif [[ ! -e /proc/$pid ]]; then
+        echo "$0: ERROR: pidfile pid $pid is not a process!!!"
+        return 1
+    fi
+    gksudo -- ip netns exec vpn gksudo -u ${SUDO_USER:-$USER} "$@"
+}
+
+transmission() {
+    vc transmission-gtk&
+    i=0
+    while ((i < 10)); do
+        tun_ip=$(s ip netns exec vpn ip a show dev tun0 | sed -rn 's/^ *inet (10\.8\.\S+).*/\1/p')
+        [[ ! $tun_ip ]] || break
+        sleep 1
+    done
+    echo "$0: tun_ip=$tun_ip"
+    [[ $tun_ip ]] || { e "$0: error: no tun0 addr found"; return 1; }
+    ssh dopub bash <<EOF
+rule="-A PREROUTING -i eth0 -p tcp -m tcp --dport 63324 -j DNAT --to-destination $tun_ip:63324"
+found=false
+while read -r line; do
+  if [[ \$line == \$rule ]] && ! \$found; then
+    found=true
+  else
+    iptables -t nat -D \${line#-A}
+  fi
+done < <(iptables -t nat -S | grep -E -- '--dport\s+63324')
+\$found || iptables -t nat \$rule
+EOF
+}
+
 virshrm() {
     for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done
 }
@@ -1084,6 +1197,7 @@ vpn() {
     journalctl --unit=openvpn@client -f -n0
 }
 
+
 vpnoff() {
     s systemctl stop openvpn@client
 }
@@ -1301,6 +1415,9 @@ fi
 # based on warning from rvmsudo
 export rvmsudo_secure_path=1
 
+# for other script I wrote
+#export ACME_TINY_PATH=/a/opt/acme-tiny
+export ACME_TINY_WRAPPER_CERT_DIR=/p/c/machine_specific/$HOSTNAME/webservercerts
 
 if [[ -s "/usr/local/rvm/scripts/rvm" ]]; then
     source "/usr/local/rvm/scripts/rvm"
@@ -1308,6 +1425,9 @@ elif [[ -s $HOME/.rvm/scripts/rvm ]]; then
     source $HOME/.rvm/scripts/rvm
 fi
 
+
+path_add --end ~/.npm-global
+
 # https://wiki.archlinux.org/index.php/Xinitrc#Autostart_X_at_login
 # i added an extra condition as gentoo xorg guide says depending on
 # $DISPLAY is fragile.