From 8d8ade781037fafe73bdb4b1a6c889b1f38d974a Mon Sep 17 00:00:00 2001 From: David Kebler Date: Tue, 3 Nov 2020 12:07:49 -0800 Subject: [PATCH] Initial commit of new shell sourcing system - base directory --- README.md | 42 +++++++ alias/00-basic | 65 +++++++++++ alias/apt | 12 ++ alias/archive/caddy | 1 + alias/archive/firehol | 7 ++ alias/archive/mint-utils | 4 + alias/archive/nas | 4 + alias/docker | 33 ++++++ alias/git | 2 + alias/iot | 4 + alias/iproute | 5 + alias/network | 2 + alias/serial | 3 + alias/systemd/networkd | 15 +++ alias/systemd/root | 11 ++ alias/systemd/user | 12 ++ app/pio | 4 + app/pm2 | 9 ++ archive/.ftpconfig.off | 23 ++++ archive/bower.off | 5 + archive/iptables | 9 ++ archive/save.off | 14 +++ env/00-shell.env | 29 +++++ env/01-opt.path | 4 + env/02-user.path | 9 ++ env/archive/path | 17 +++ env/editor.env | 3 + env/gcc.env | 2 + env/git.env | 1 + env/history.env | 7 ++ env/modules.env | 7 ++ env/ssh.env | 2 + function/00-basic | 38 ++++++ function/archive/aws | 46 ++++++++ function/archive/aws-recordset | 86 ++++++++++++++ function/archive/aws-set-network-ip-old | 105 +++++++++++++++++ function/archive/caddy | 12 ++ function/archive/nas | 21 ++++ function/archive/test | 1 + function/helpers | 40 +++++++ function/logit | 19 +++ function/ssh | 4 + function/systemd | 40 +++++++ lang/go | 5 + lang/node | 53 +++++++++ lang/python | 12 ++ lang/yarn | 19 +++ misc/less | 2 + misc/prompt | 27 +++++ misc/xterm | 5 + modules/bind-mount/bind-mount.sh | 24 ++++ modules/editing/block/block.sh | 147 ++++++++++++++++++++++++ modules/editing/block/test/test.sh | 30 +++++ modules/editing/replace/replace.sh | 39 +++++++ modules/editing/replace/replace.sh.save | 39 +++++++ modules/module.sh | 141 +++++++++++++++++++++++ modules/modules.sh | 11 ++ modules/sshfs/sshfs.sh | 31 +++++ modules/usage | 6 + options | 20 ++++ setup.sh | 78 +++++++++++++ source-dir.func | 109 ++++++++++++++++++ 62 files changed, 1577 insertions(+) create mode 100644 README.md create mode 100644 alias/00-basic create mode 100644 alias/apt create mode 100644 alias/archive/caddy create mode 100644 alias/archive/firehol create mode 100644 alias/archive/mint-utils create mode 100644 alias/archive/nas create mode 100644 alias/docker create mode 100644 alias/git create mode 100644 alias/iot create mode 100644 alias/iproute create mode 100644 alias/network create mode 100644 alias/serial create mode 100644 alias/systemd/networkd create mode 100644 alias/systemd/root create mode 100644 alias/systemd/user create mode 100644 app/pio create mode 100644 app/pm2 create mode 100644 archive/.ftpconfig.off create mode 100644 archive/bower.off create mode 100644 archive/iptables create mode 100644 archive/save.off create mode 100644 env/00-shell.env create mode 100644 env/01-opt.path create mode 100644 env/02-user.path create mode 100644 env/archive/path create mode 100644 env/editor.env create mode 100644 env/gcc.env create mode 100644 env/git.env create mode 100644 env/history.env create mode 100644 env/modules.env create mode 100644 env/ssh.env create mode 100644 function/00-basic create mode 100755 function/archive/aws create mode 100644 function/archive/aws-recordset create mode 100644 function/archive/aws-set-network-ip-old create mode 100644 function/archive/caddy create mode 100644 function/archive/nas create mode 100644 function/archive/test create mode 100644 function/helpers create mode 100644 function/logit create mode 100644 function/ssh create mode 100644 function/systemd create mode 100644 lang/go create mode 100644 lang/node create mode 100644 lang/python create mode 100644 lang/yarn create mode 100644 misc/less create mode 100644 misc/prompt create mode 100644 misc/xterm create mode 100755 modules/bind-mount/bind-mount.sh create mode 100755 modules/editing/block/block.sh create mode 100755 modules/editing/block/test/test.sh create mode 100755 modules/editing/replace/replace.sh create mode 100644 modules/editing/replace/replace.sh.save create mode 100644 modules/module.sh create mode 100644 modules/modules.sh create mode 100755 modules/sshfs/sshfs.sh create mode 100644 modules/usage create mode 100644 options create mode 100755 setup.sh create mode 100644 source-dir.func diff --git a/README.md b/README.md new file mode 100644 index 0000000..01be26e --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# Bash Shell Setup Repo +A better way to keep organized and share interactive (.bashrc) environment, aliases, functions, modules + +## Install + +Clone to a directory + +`git clone https://git.kebler.net/bashrc ` e.g. /opt/shell + +now edit your `~/.bashrc` with nano or other available editor + +add this +``` +export BASH_SHELL_REPO=/setup. +source $BASH_SHELL_REPO/setup.sh +``` + +The idea is to keep the .bashrc file completely clean and manage this repo instead +so you should really find a home for all the existing content of your .bashrc file within the repo + +Every file in `env` `functions`,`aliases` and `misc` subdirectories will be sourced in that order (in setup.sh). Within each folder all files are sourced except ones ending with a `.off` extension, starting with `.` and the README.md file plus any in any subfolder except `/archive` or ` /dep` + +The sourced files in this repo should be NOT be user/machine/network specific + +if you include any of these environment variables all files in there directories will be sourced where + + +export BASH_SHELL_USER= # will be in home/ +export BASH_SHELL_MACHINE= #parent directory e.g. opt/shell/machine +export BASH_SHELL_NETWORK= #parent directory e.g. opt/shell/network + +if there is a script setup.sh in the root of these directoies it will be run. If not then all files no matter how deep will be sourced in alpha order order. + +For those + +If need to turn off a file just add `.off` to the file name rather than move or delete the file...simple. + +If you are really done with something but want to keep a copy in the repo move it to /archive folder within the primary subfolders + +if sourcing some file depends on another preface with numbers to put it before. Functions are all sourced before aliases so can be refered to there. + +Be aware that an alias or function set in the repo could be subsuming some existing binary or script. diff --git a/alias/00-basic b/alias/00-basic new file mode 100644 index 0000000..73ba31b --- /dev/null +++ b/alias/00-basic @@ -0,0 +1,65 @@ +# 00 will get loaded first + +alias flist="function_list" +alias flistg="function_list | grep" +alias aliasg="alias | grep " + +alias envg="env | grep " + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# brings user path to sudo +alias sudoi='sudo -i env PATH=$PATH' +alias sudoh='sudo -H' + +alias reboot="sudo systemctl reboot" +alias poweroff="sudo systemctl poweroff" + +# search for a running process +alias psl='ps -ef | grep' +# kill any process containing given name +alias ska='sudo killall' +alias ka='killall' +# kill processes greped +alias skg='sudo pkill -f' +alias kg='pkill -f' + +alias df='df -h -x supermount' +alias du='du -h' +alias egrep='egrep --color' +alias fgrep='fgrep --color' +alias grep='grep --color' + +# Directory/File +alias ls='ls -F --color=auto' +alias l='ls' +alias la='ls -a' +alias ll='ls -l' +alias lla='ls -l -a' +alias llag='ls -l -a | grep' +alias lsd='ls -d */' +alias md='mkdir' +alias mv='mv -i' +alias p='cd -' +alias rd='rmdir' +alias rm='rm -i' +alias cd..='cd ..' +alias cp='cp -i' +alias mpath="echo $PATH" # machine path per /etc/environment +alias path='echo $PATH' +alias sysinfo='sudo inxi -Fzxd' + +alias efstab="cp /etc/fstab ~/fstab.bak && gedit admin:/etc/fstab" +alias ea="editor ~/.bash_aliases" +alias ead="editor ~/.kbd-aliases/" +alias eadg="editor ~/.kbd-aliases/" +alias eag="editor ~/.bash_aliases" +alias essh="sudo editor /etc/ssh/sshd_config" +alias ebrc='editor ~/.bashrc' +# follows a link to list the source path +alias follow="readlink -f" + +# Will scrub all and reload only aliases in .bash_aliaes +alias reloada="unalias -a && source ~/.bash_aliases && compgen -a" diff --git a/alias/apt b/alias/apt new file mode 100644 index 0000000..e8cc609 --- /dev/null +++ b/alias/apt @@ -0,0 +1,12 @@ +# apt package manager +alias installa="sudo apt-get install" +alias reinstall="sudo apt install --reinstall" +# change depending on distro - need to have backports loaded in apt sources +# FYI can just load individual binaries from the wiki using deb files say from testing or unstable +alias remove="sudo apt-get remove" +alias aremove="sudo apt-get autoremove" +alias purge="sudo apt-get purge" +alias update="sudo apt-get update" +alias pkgst="apt policy" +alias esources='sudo nano /etc/apt/sources.list.d/' +alias ppa='sh -c '\''sudo add-apt-repository ppa:$1/ppa'\'' _' diff --git a/alias/archive/caddy b/alias/archive/caddy new file mode 100644 index 0000000..70f79c8 --- /dev/null +++ b/alias/archive/caddy @@ -0,0 +1 @@ +alias caddyr="ssh -t nas "/opt/scripts/caddyr"" diff --git a/alias/archive/firehol b/alias/archive/firehol new file mode 100644 index 0000000..aed134d --- /dev/null +++ b/alias/archive/firehol @@ -0,0 +1,7 @@ +# using firehol +alias fwstp="sudo firehol stop" +alias fws="sudo firehol start" +alias fwdf="/opt/firehol/scripts/default" +alias fwt="/opt/firehol/scripts/try" +alias fwdb="/opt/firehol/scripts/debug" +alias fwm="/opt/firehol/scripts/merge" diff --git a/alias/archive/mint-utils b/alias/archive/mint-utils new file mode 100644 index 0000000..5065fe2 --- /dev/null +++ b/alias/archive/mint-utils @@ -0,0 +1,4 @@ +# run this on remote machine via ssh x11 forwarding +alias rmintupdate='XAUTHORITY=/home/sysadmin/.Xauthority sudo -E mintupdate' +alias rsources='XAUTHORITY=/home/sysadmin/.Xauthority sudo -E software-sources' +alias rsynaptic='XAUTHORITY=/home/sysadmin/.Xauthority sudo -E synaptic' diff --git a/alias/archive/nas b/alias/archive/nas new file mode 100644 index 0000000..1c3486e --- /dev/null +++ b/alias/archive/nas @@ -0,0 +1,4 @@ +# nas +alias naslist="echo nasfm nasdisk nasgparted nasdata, caddyr, caddye" +alias nasha="ssh -t nas 'cd /usr/share/hassio/homeassistant ; bash'" +alias nascaddy="ssh -t nas 'cd /opt/caddy ; bash'" diff --git a/alias/docker b/alias/docker new file mode 100644 index 0000000..869db8c --- /dev/null +++ b/alias/docker @@ -0,0 +1,33 @@ +#!/bin/bash +if command -v docker >/dev/null 2>&1; then + +#docker - add users to docker group to avoid needing sudo +# run a command on a container +# if [ $(which docker)]; then + +alias dkcr="docker run" +# start a container +alias dkcs="docker start" +# restart all running containers +alias dkcrr="docker restart $(docker ps -q)" +# start all exited containers +alias dkcsu="docker start $(docker ps --filter "status=exited")" +# ls stopped, la all, l running +alias dkcls="docker ps --filter "status=exited"" +alias dkcla="docker ps -a " +alias dkcl="docker ps " +alias dkil="docker images --digests=true" +alias dkir="docker rmi $(docker images -q)" +alias dks="sudo service docker" +alias dkcstpa="docker stop $(docker ps -a -q)" +# remove unrunning containers +alias dkcrm="docker rm $(docker ps -a -q)" +# stop and remove +alias dkcsrm="docker rm -f $(docker ps -a -q)" +# cleans out unused/dangling aufs volumes - run this occasionally +alias dkclean="docker volume ls -qf dangling=true | xargs -r docker volume rm" +alias dkde="gksudo gedit /etc/default/docker" + +# else +# echo "docker not installed, aliases not loaded" +fi diff --git a/alias/git b/alias/git new file mode 100644 index 0000000..77de38c --- /dev/null +++ b/alias/git @@ -0,0 +1,2 @@ +alias gspa="git subrepo push --all" +alias gpom="git pull origin master" # update repo from default remove diff --git a/alias/iot b/alias/iot new file mode 100644 index 0000000..da7ca87 --- /dev/null +++ b/alias/iot @@ -0,0 +1,4 @@ +# i2c +alias i2cs='i2cdetect -y 1' +alias erpic='sudo editor /boot/config.txt' +alias gerpic='gksu pluma /boot/config.txt' diff --git a/alias/iproute b/alias/iproute new file mode 100644 index 0000000..5b6f889 --- /dev/null +++ b/alias/iproute @@ -0,0 +1,5 @@ +# bring an interface up or down +alias nid="sudo ip link set down" +alias niu="sudo ip link set up" +# restart wan interface including networkd restart +alias nir1="nid wan && niu wan && nwr" diff --git a/alias/network b/alias/network new file mode 100644 index 0000000..cb1867f --- /dev/null +++ b/alias/network @@ -0,0 +1,2 @@ +alias ports="netstat -tulpn" +alias flushdns="systemctl restart systemd-resolved" diff --git a/alias/serial b/alias/serial new file mode 100644 index 0000000..758b467 --- /dev/null +++ b/alias/serial @@ -0,0 +1,3 @@ +alias sports='dmesg | egrep --color "serial|tty"' +alias connewest='screen $(ls -tw 1 /dev/tty* | head -1) 115200' +alias conacm0='screen /dev/ttyACM0 115200' diff --git a/alias/systemd/networkd b/alias/systemd/networkd new file mode 100644 index 0000000..d2ff3ad --- /dev/null +++ b/alias/systemd/networkd @@ -0,0 +1,15 @@ +alias nws="sudo systemctl start systemd-networkd" +alias nwe="sudo systemctl enable systemd-networkd" +alias nwd="sudo systemctl disable systemd-networkd" +alias nwstp="sudo systemctl stop systemd-networkd" +alias nwr="sudo systemctl restart systemd-networkd" +alias nwdst="systemctl status systemd-networkd" +alias nwj="journalctl -u systemd-networkd" +alias nw="networkctl" +alias nwst="networkctl status" +alias nwl="networkctl lldp" + +alias nid="sudo ip link set down" +alias niu="sudo ip link set up" +alias nir1="nid eth1 && niu eth1 && nwr" +alias nir1="nid eth1 && niu eth1 && nwr" diff --git a/alias/systemd/root b/alias/systemd/root new file mode 100644 index 0000000..52cb476 --- /dev/null +++ b/alias/systemd/root @@ -0,0 +1,11 @@ +alias sdst="sudo systemctl status" +alias sds="sudo systemctl start" +alias sdr="sudo systemctl restart" +alias sde="sudo systemctl enable" +alias sdstp="sudo systemctl stop" +alias sdd="sudo systemctl disable" +alias sdrld="sudo systemctl daemon-reload" +alias sdla="systemctl list-units | grep" +alias sdl="systemctl list-unit-files | grep" +alias sdle="systemctl list-unit-files | grep enabled" +alias sdpidu="systemctl show --property MainPID --value" diff --git a/alias/systemd/user b/alias/systemd/user new file mode 100644 index 0000000..b4f8f72 --- /dev/null +++ b/alias/systemd/user @@ -0,0 +1,12 @@ +# user versions +alias sdstu="systemctl --user status" +alias sdsu="systemctl --user start" +alias sdru="systemctl --user restart" +alias sdeu="systemctl --user enable" +alias sdstpu="systemctl --user stop" +alias sdrldu="systemctl --user daemon-reload" +alias sddu="systemctl --user disable" +alias sdlau="systemctl --user list-units | grep" +alias sdlu="systemctl --user list-unit-files | grep" +alias sdleu="systemctl --user list-unit-files | grep enabled" +alias sdpidu="systemctl show --user --property MainPID --value" diff --git a/app/pio b/app/pio new file mode 100644 index 0000000..1414b00 --- /dev/null +++ b/app/pio @@ -0,0 +1,4 @@ +# pio in path and completion for platformio subcommands +export PATH=$PATH:~/.platformio/penv/bin +eval "$(_PLATFORMIO_COMPLETE=source platformio)" +eval "$(_PIO_COMPLETE=source pio)" diff --git a/app/pm2 b/app/pm2 new file mode 100644 index 0000000..6302697 --- /dev/null +++ b/app/pm2 @@ -0,0 +1,9 @@ +alias pmi="sudo pm2 install" +alias pms="sudo pm2 start" +alias pmstp="sudo pm2 stop" +alias pmr="sudo pm2 delete" +alias pmra="sudo pm2 delete all" +alias pmstpa="sudo pm2 stop all" +alias pmv="sudo pm2 save" +alias pml="sudo pm2 list" +alias pmm="sudo pm2 monit" diff --git a/archive/.ftpconfig.off b/archive/.ftpconfig.off new file mode 100644 index 0000000..2f544e0 --- /dev/null +++ b/archive/.ftpconfig.off @@ -0,0 +1,23 @@ +{ + "protocol": "sftp", + "host": "router", + "port": 22, + "user": "sysadmin", + "pass": "", + "promptForPass": false, + "remote": "/home/sysadmin/.kbd-aliases", + "local": "", + "agent": "env", + "privatekey": "", + "passphrase": "", + "hosthash": "", + "ignorehost": true, + "connTimeout": 10000, + "keepalive": 10000, + "keyboardInteractive": false, + "keyboardInteractiveForPass": false, + "remoteCommand": "", + "remoteShell": "", + "watch": [], + "watchTimeout": 500 +} diff --git a/archive/bower.off b/archive/bower.off new file mode 100644 index 0000000..20151ba --- /dev/null +++ b/archive/bower.off @@ -0,0 +1,5 @@ +# bower +alias bidv="bower install --save-dev" +alias brdv="bower uninstall --save-dev" +alias bi="bower install --save" +alias br="bower uninstall --save" diff --git a/archive/iptables b/archive/iptables new file mode 100644 index 0000000..378d19e --- /dev/null +++ b/archive/iptables @@ -0,0 +1,9 @@ +alias iptl="sudo iptables -S" +alias iptlf="sudo iptables -L" +alias iptln="sudo iptables -L -t nat" +alias iptd="sudo /etc/iptables/iptables-default.sh" +alias iptf="sudo /etc/iptables/iptables-flush.sh" +alias ipts="sudo systemctl start iptables" +alias iptst="sudo systemctl status iptables" +alias iptstp="sudo systemctl stop iptables" +alias iptstpp="sudo /etc/iptables/iptables-default.sh" diff --git a/archive/save.off b/archive/save.off new file mode 100644 index 0000000..14a8c3e --- /dev/null +++ b/archive/save.off @@ -0,0 +1,14 @@ +# if parameter(s) is needed instead of just at the end of alias then create a "little" function instead. +# like mymv() { mv $1 $2; } +# or rsynchc() { rsync --help | grep "\-$1"; } + + +alias sdns="nmcli device show eth0 | grep IP4.DNS" +# shows running processes with ntfs that might hang gparted, then kill with next command +alias ntfs='ps -ef | egrep "dosfsck|ntfs"' + +alias lo="gnome-session-quit" + +#mongo via docker container name mongodbmo +alias mg="docker exec -it mongodbserver mongo" +alias mongodb="docker exec -it mongodbserver mongo" diff --git a/env/00-shell.env b/env/00-shell.env new file mode 100644 index 0000000..093bf4a --- /dev/null +++ b/env/00-shell.env @@ -0,0 +1,29 @@ +# Additional Shell Repos to Source +# BASH_SHELL is a common parent directory that should be set in /etc/bash.bashrc +# unless below specific directories are set +# shell files are sourced in this order +# sourced via /etc/bash.bashrc so for all machine users +# $BASH_SHELL_BASE # this MUST be set in /etc/bash.bashrc +# $BASH_SHELL_NETWORK/all +# $BASH_SHELL_NETWORK/$NETWORKNAME +# $BASH_SHELL_HOST/all +# $BASH_SHELL_HOST/ +# sourced via $HOME/.bashrc +# $HOME/shell or $HOME/BASH_SHELL_USER + +# within each of those directories if setup.sh exits it will be run +# otherwise files will be sourced exactly like in the base + +# identify a network name that this host resides on +# like hostname but for the LAN network +# if unset then only /all will be sourced +export NETWORKNAME=238 +# will use $BASH_SHELL_NETWORK/$NETWORKNAME under this directory unless specifically set +export BASH_SHELL_NETWORK=$BASH_SHELL/network + +# will use $BASH_SHELL_HOST/ unless specifically set +export BASH_SHELL_HOST=$BASH_SHELL/host + +# by default SHELL sources will be looked for under $HOME/bash/shell +# but can be user set below to $HOME/$BASH_SHELL_USER +# export BASH_SHELL_USER= diff --git a/env/01-opt.path b/env/01-opt.path new file mode 100644 index 0000000..0f4ee81 --- /dev/null +++ b/env/01-opt.path @@ -0,0 +1,4 @@ +# set PATH so it includes user's private bin if it exists +if [ -d "/opt/bin" ] ; then + PATH="/opt/bin:$PATH" +fi diff --git a/env/02-user.path b/env/02-user.path new file mode 100644 index 0000000..80c490d --- /dev/null +++ b/env/02-user.path @@ -0,0 +1,9 @@ +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" +fi diff --git a/env/archive/path b/env/archive/path new file mode 100644 index 0000000..689062d --- /dev/null +++ b/env/archive/path @@ -0,0 +1,17 @@ +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" +fi + +# if running bash +if [ -n "$BASH_VERSION" ]; then + # include .bashrc if it exists + if [ -f "$HOME/.bashrc" ]; then + . "$HOME/.bashrc" + fi +fi diff --git a/env/editor.env b/env/editor.env new file mode 100644 index 0000000..487434e --- /dev/null +++ b/env/editor.env @@ -0,0 +1,3 @@ +# used by aliases that need an editor +export EDITOR=atom +# export EDITOR=nano diff --git a/env/gcc.env b/env/gcc.env new file mode 100644 index 0000000..63f3155 --- /dev/null +++ b/env/gcc.env @@ -0,0 +1,2 @@ +# colored GCC warnings and errors +export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' diff --git a/env/git.env b/env/git.env new file mode 100644 index 0000000..28e149e --- /dev/null +++ b/env/git.env @@ -0,0 +1 @@ +export GIT_SSL_NO_VERIFY=1 diff --git a/env/history.env b/env/history.env new file mode 100644 index 0000000..37fef9c --- /dev/null +++ b/env/history.env @@ -0,0 +1,7 @@ +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 diff --git a/env/modules.env b/env/modules.env new file mode 100644 index 0000000..db3cc6f --- /dev/null +++ b/env/modules.env @@ -0,0 +1,7 @@ +# All the directories which contain based modules/libraries +# module libraries will be look up in this order +# first set any additional modules directories to search (if any) +# MODULE_DIRS=() +# those will be searched first then /modules under the shell directories +# user,host,network,base in that order +# this provide a way to override a module with a more specific version diff --git a/env/ssh.env b/env/ssh.env new file mode 100644 index 0000000..16f7c0b --- /dev/null +++ b/env/ssh.env @@ -0,0 +1,2 @@ +# set ssh agent socket for each session +export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" diff --git a/function/00-basic b/function/00-basic new file mode 100644 index 0000000..bd863af --- /dev/null +++ b/function/00-basic @@ -0,0 +1,38 @@ +#!/bin/bash +# 00 will get loaded first + +##-- functions which may be used by any of the alias file --# + +function function_list() { + echo + echo -e "\033[1;4;32m""Functions:""\033[0;34m" + declare -F | grep -v "declare -f\s_" | awk {'print $3'} + echo + echo -e "\033[0m" +} + +function alias_list() { + echo + echo -e "\033[1;4;32m""Aliases:""\033[0;34m" + alias | awk {'print $2'} | awk -F= {'print $1'} + echo + echo -e "\033[0m" +} + +rsynchc() { rsync --help | grep "\-$1"; } +alias rsynch="rsynchc" + +change-ext() { +shopt -s globstar +rename -n 's/.'+$1+'/.'+$2+'/' ** +} +alias chext=change-ext + +# find in any file +fif() { +grep -rnswl $1 -e $2 | more +} + +# edit files +# set the system editor using EDITOR environment variable +editor() { ${EDITOR} $1; } diff --git a/function/archive/aws b/function/archive/aws new file mode 100755 index 0000000..14ef56b --- /dev/null +++ b/function/archive/aws @@ -0,0 +1,46 @@ +#!/bin/bash +# aws cli from docker image on any machine +function aws() { +AWS_CLI_IMAGE=${AWS_CLI_IMAGE:-amazon/aws-cli:latest} +AWS_WORKING_DIR=${AWS_WORKING_DIR:-$HOME/awscli} +local cmd +cmd="docker run --rm -ti + --env AWS_ACCESS_KEY_ID + --env AWS_CONFIG_FILE + --env AWS_SHARED_CREDENTIALS_FILE + --env AWS_SECRET_ACCESS_KEY + --env AWS_DEFAULT_REGION + -v ${HOME}/.aws:/root/.aws + -v ${AWS_WORKING_DIR}:/aws + ${AWS_CLI_IMAGE} $* + --no-cli-pager + " + # echo ${cmd} + # local res + echo "$(eval ${cmd})" + # echo $RES + +} + +# `! [ -z $AWS_ACCESS_KEY_ID ] && echo "--env AWS_ACCESS_KEY_ID"` \ +# `! [ -z $AWS_SECRET_ACCESS_KEY ] && echo "--env AWS_SECRET_ACCESS_KEY"` \ +# `! [ -z $AWS_DEFAULT_REGION ] && echo "--env AWS_DEFAULT_REGION"` \ + +test () { + +echo $(aws route53 list-hosted-zones) + +} + +aws-get-zone-id () { +local records +local domain +domain=$(get-domain $1) +echo $domain +aws route53 list-hosted-zones --query "'HostedZones[?Name==\`${domain}.\`]'" +echo returned +echo $RES +# local res +# res=$(echo $records | grep ID | awk -F'[\"#]+' '{print $4}' | awk -F'[/#]+' '{print $3}') +# echo "$res" +} diff --git a/function/archive/aws-recordset b/function/archive/aws-recordset new file mode 100644 index 0000000..84e534d --- /dev/null +++ b/function/archive/aws-recordset @@ -0,0 +1,86 @@ +#!/bin/bash + +function aws-get-zone-record () { + local record + echo get record $1 $(get-domain $1) + record=$( + aws route53 list-resource-record-sets \ + --hosted-zone-id $(aws-get-zone-id $1) + ) + echo "$record" +} + +function aws-get-zone-record-prop () { + local record + record=$(aws-get-zone-record $1) + local res + res=$(get-prop-value "$record" $2) + echo "$res" +} + + +function aws-get-zone-record-value () { + local record + record=$(aws-get-zone-record $1) + local res + res=$(get-prop-value "$record" "ResourceRecords[0].Value") + echo "$res" +} + +function aws-update-zone-record-value () { + +if [ "$#" -ne 2 ]; then + echo "Both recordset and value required" + exit 0 +fi + +RECORDSET=$1 +VALUE=$2 +COMMENT=${3:-"Updating Record"} +RECORD=$(aws-get-zone-record "$RECORDSET") +echo the reccord $RECORD +# ZONENAME=$(get-domain $RECORDSET) +ZONEID=$(aws-get-zone-id "$(get-domain $RECORDSET )") +# The Time-To-Live of this recordset +# echo Zone Name and ID for recordset $RECORDSET $ZONENAME $ZONEID +# TTL=60 # call this later with increase + # Fill a temp file with valid JSON +CHANGE="{ + \"Comment\":\"$COMMENT\", + \"Changes\":[ + { + \"Action\":\"UPSERT\", + \"ResourceRecordSet\":{ + \"ResourceRecords\":[ + { + \"Value\":\"$VALUE\" + } + ], + \"Name\":\"$RECORDSET\", + \"Type\":\"$(get-prop-value "$RECORD" Type)\", + \"TTL\":\"$(get-prop-value "$RECORD" TTL)\" + } + } + ] +} +" +echo updating record with +batch=\'${CHANGE}\' +echo batch + + + # Update the Hosted Zone record +CMD="aws route53 change-resource-record-sets + --hosted-zone-id ${ZONEID} + --change-batch $batch + " + +echo "${CMD}" +local res +res=$($CMD) +echo "$res" + + +# echo confirm change $(aws-get-zone-record-value $RECORDSET) +# end function +} diff --git a/function/archive/aws-set-network-ip-old b/function/archive/aws-set-network-ip-old new file mode 100644 index 0000000..81986c6 --- /dev/null +++ b/function/archive/aws-set-network-ip-old @@ -0,0 +1,105 @@ +#!/bin/bash +function route53-set-record () { +# (optional) You might need to set your PATH variable at the top here +# depending on how you run this script +# PATH=PATH + +# Hosted Zone ID e.g. BJBK35SKMM9OE +ZONEID="ZF04FGKB9QHN2" + +# The CNAME you want to update e.g. hello.example.com +RECORDSET="238.kebler.net" + +# More advanced options below +# The Time-To-Live of this recordset +TTL=300 +# Change this if you want +COMMENT="Auto updating @ `date`" +# Change to AAAA if using an IPv6 address +TYPE="A" + +# Get the external IP address from OpenDNS (more reliable than other providers) +IP=`dig +short myip.opendns.com @resolver1.opendns.com` + +echo current ip is $IP + + +# Get current dir +# (from http://stackoverflow.com/a/246128/920350) +# DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +DIR=$HOME +LOGFILE="$DIR/update-route53.log" +IPFILE="$DIR/update-route53.ip" + +if ! valid_ip $IP; then + echo "Invalid IP address: $IP" >> "$LOGFILE" + exit 1 +fi + +# Check if the IP has changed +if [ ! -f "$IPFILE" ] + then + touch "$IPFILE" +fi + +if grep -Fxq "$IP" "$IPFILE"; then + # code if found + echo "IP is still $IP. Exiting" >> "$LOGFILE" + exit 0 +else + echo "IP has changed to $IP" >> "$LOGFILE" + # Fill a temp file with valid JSON + TMPFILE=$(mktemp /tmp/temporary-file.XXXXXXXX) + cat > ${TMPFILE} << EOF + { + "Comment":"$COMMENT", + "Changes":[ + { + "Action":"UPSERT", + "ResourceRecordSet":{ + "ResourceRecords":[ + { + "Value":"$IP" + } + ], + "Name":"$RECORDSET", + "Type":"$TYPE", + "TTL":$TTL + } + } + ] + } +EOF + + # Update the Hosted Zone record + aws route53 change-resource-record-sets \ + --hosted-zone-id $ZONEID \ + --change-batch file://"$TMPFILE" >> "$LOGFILE" + echo "IP Changed in Route53" >> "$LOGFILE" + + # Clean up + rm $TMPFILE +fi + +# All Done - cache the IP address for next time +echo "$IP" > "$IPFILE" + +} +# end function + +function valid_ip() +{ + local ip=$1 + local stat=1 + + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + OIFS=$IFS + IFS='.' + ip=($ip) + IFS=$OIFS + [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ + && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] + stat=$? + fi + return $stat +} diff --git a/function/archive/caddy b/function/archive/caddy new file mode 100644 index 0000000..f50ca02 --- /dev/null +++ b/function/archive/caddy @@ -0,0 +1,12 @@ +#!/bin/bash +function caddye(){ + rrem sysadmin@nas.kebler.net "gedit /opt/caddy/caddy.conf" +} + +function caddys(){ + rrem sysadmin@nas.kebler.net "sudo systemctl status caddy" +} + +function caddyj(){ + rrem sysadmin@nas.kebler.net "journalctl -u caddy | tail -f -n -100" +} diff --git a/function/archive/nas b/function/archive/nas new file mode 100644 index 0000000..a164e7a --- /dev/null +++ b/function/archive/nas @@ -0,0 +1,21 @@ +#!/bin/bash +# nas + +## rrem already loaded in 00-basic + +function nasfm(){ + rrem sysadmin@nas.kebler.net "nemo $1" +} + +function nasdisk(){ + rrem sysadmin@nas.kebler.net "sudo gnome-disks" +} + + +function nasgparted(){ + rrem sysadmin@nas.kebler.net "sudo gparted" +} + +function nasdata(){ + rrem sysadmin@nas.kebler.net "nemo /mnt/data" +} diff --git a/function/archive/test b/function/archive/test new file mode 100644 index 0000000..3725cda --- /dev/null +++ b/function/archive/test @@ -0,0 +1 @@ +A test diff --git a/function/helpers b/function/helpers new file mode 100644 index 0000000..d66c16b --- /dev/null +++ b/function/helpers @@ -0,0 +1,40 @@ +#!/bin/bash +valid_ip() +{ + local ip=$1 + local stat=1 + local res + + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + OIFS=$IFS + IFS='.' + ip=($ip) + IFS=$OIFS + [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ + && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] + res=$([ $? == 0 ] && echo true || echo false) + else + res=false + fi + echo $res +} + +get_domain() { +local domain +domain=$(echo $1 | awk -F\. '{print $(NF-1) FS $NF}') +echo "$domain" +} + +# must be json as a string, depends on jq +get_prop_value () { + local value + # echo in $1 get $2 + value=$(echo $1 | jq -r .$2) + echo $value +} + + +is_array() { + local variable_name=$1 + [[ "$(declare -p $variable_name 2>/dev/null)" =~ "declare -a" ]] +} diff --git a/function/logit b/function/logit new file mode 100644 index 0000000..50465fb --- /dev/null +++ b/function/logit @@ -0,0 +1,19 @@ +#!/bin/bash +function logit(){ + local SCRIPT_PATH + local LOG_PATH + local SCRIPT_DIR + local SCRIPT_NAME + + tty -s + if [ "0" != "$?" ] || [ $1 == f ]; then + SCRIPT_PATH=$(readlink -f "$0") + SCRIPT_DIR=$(dirname $SCRIPT_PATH) + SCRIPT_NAME=$(basename ${SCRIPT_PATH%.*}) + mkdir -p $SCRIPT_DIR/logs + # log is the /logs subdirectory of original script directory + LOG_PATH="$SCRIPT_DIR/logs/$SCRIPT_NAME.log" + exec 1> $LOG_PATH 2>&1 + echo $(date) logging for $SCRIPT_PATH + fi +} diff --git a/function/ssh b/function/ssh new file mode 100644 index 0000000..262178a --- /dev/null +++ b/function/ssh @@ -0,0 +1,4 @@ +# remote start a program (with x11 forwarding will render locally if gui) +function rrem(){ + ssh -X -t "$1" """$2" "$3""" +} diff --git a/function/systemd b/function/systemd new file mode 100644 index 0000000..6e0703a --- /dev/null +++ b/function/systemd @@ -0,0 +1,40 @@ +#!/bin/bash +function sdj(){ + journalctl -u "$1" | tail -f -n ${2:-50} + } +function sdjf(){ + journalctl -f -u "$1" + } +function sdw(){ + sdst "$1" | grep Loaded + } + +function sdstate () { + echo $1 state + systemctl show --no-page $1 | grep ActiveState + systemctl show --no-page $1 | grep UnitFileState + systemctl show --no-page $1 | grep LoadState + systemctl show --no-page $1 | grep ExecMainPID + systemctl show --no-page $1 | grep ExecMainStartTimestamp= + systemctl show --no-page $1 | grep ExecMainExitTimestamp= + } + +function sdju(){ + journalctl --user -u "$1" | tail -f -n ${2:-50} + } +function sdjuf(){ + journalctl --user -f -u "$1" + } +function sdwu(){ + sdstu "$1" | grep Loaded + } + +function sdstateu () { +echo $1 state +systemctl --user show --no-page $1 | grep ActiveState +systemctl --user show --no-page $1 | grep UnitFileState +systemctl --user show --no-page $1 | grep LoadState +systemctl --user show --no-page $1 | grep ExecMainPID +systemctl --user show --no-page $1 | grep ExecMainStartTimestamp= +systemctl --user show --no-page $1 | grep ExecMainExitTimestamp= +} diff --git a/lang/go b/lang/go new file mode 100644 index 0000000..d316495 --- /dev/null +++ b/lang/go @@ -0,0 +1,5 @@ +# GoLang +export GOROOT=/opt/go/bin +export PATH=$GOROOT/bin:$PATH +export GOPATH=/opt/go/workspace +export PATH=$GOPATH/bin:$PATH diff --git a/lang/node b/lang/node new file mode 100644 index 0000000..227917f --- /dev/null +++ b/lang/node @@ -0,0 +1,53 @@ +#!/bin/bash + +if command -v node >/dev/null 2>&1; then +# gives access to packages with bin in a project +export PATH=$PATH:./node_modules/.bin +export PATH=$PATH:/opt/node-global-apps/bin + + +export NPM_REGISTRY=https://npm.kebler.net +alias nr="npm run" +alias nrs="npm -s run" +alias nt="npm -s test" +alias ntw="npm -s run testw" +alias npms="npm start" +alias npmlag="npm la --silent --depth=0 --global" +alias npmla="npm la --silent --depth=0" +alias npmlaf="npm la --silent | grep" +alias npmlsg="npm ls --silent --depth=0 --global" +alias npmlsf="npm ls --silent grep" +alias npmlsa="npm ls --silent" +alias npmls="npm ls --silent --depth=0" +# just npm install for install without saving into package.json +alias npmi="npm install --save" +alias npmr="npm uninstall --save" +alias npmio="npm install --save-optional" +alias npmro="npm uninstall --save-optional" +alias npmidv="npm install --save-dev" +alias npmidvnd="npm install --save-dev --package-lock-only --no-package-lock" +alias npmrdv="npm uninstall --save-dev" +alias npmig="npm install -g" +alias snpmig="sudo npm install -g" +alias npmrg="npm uninstall -g" +alias snpmrg="npm uninstall -g" +alias npmunpm="echo npm installed version && npm --version && echo npm latest version available && npm view npm@latest version && echo any key to continue npm upgrade or break && read && npm install -g npm@latest" +alias npmua="npm --depth=9999 update" +alias npmug="npm-check -g -u" +alias npmu="npm-check -u" +alias npmcc="ncu -p -a -u" +alias npmcdvc="ncu -d -a -u" +alias npmc="ncu -p" +alias npma="npm-add-dependencies" +# will publish to whichever is the default registry - confusing so commented out +# alias npmpub="npm publish --access public" +alias npmlrepub="npm publish --registry http://localhost:4873 --force --access restricted" +alias npmlpub="npm publish --registry http://localhost:4873 --access restricted" +alias npmnrepub="npm publish --registry https://npm.kebler.net --force --access restricted" +alias npmnpub="npm publish --registry https://npm.kebler.net --access restricted" +alias npmjspub="npm publish --registry https://registry.npmjs.org --access public" +alias yalcpush="nodemon -x 'yalc push'" + +# else + # echo "node not installed, npm aliases not loaded" +fi diff --git a/lang/python b/lang/python new file mode 100644 index 0000000..d5223bb --- /dev/null +++ b/lang/python @@ -0,0 +1,12 @@ +alias python3="python3.8" +alias spip="sudo -H python3.8 -m pip" +alias spipi="sudo -H python3.8 -m pip install" +alias spipiu="sudo -H python3.8 -m pip install -U" +alias spipl="sudo -H python3.8 -m pip list" +alias spiplo="sudo -H python3.8 -m pip list --outdated" +alias pipu="pipx upgrade" +alias pipua="pipx upgrade-all" +alias pipupip="pipx upgrade pipx" +alias pipi="pipx install" +alias pipl="pipx list" +alias piplv="pipx list --verbose" diff --git a/lang/yarn b/lang/yarn new file mode 100644 index 0000000..6b4f5ce --- /dev/null +++ b/lang/yarn @@ -0,0 +1,19 @@ +alias ycc="yarn cache clean" +alias yr="yarn run" +alias ys="yarn run start" +alias ya="yarn add" +# alias yu="yarn upgrade" +alias yrm="yarn remove" +alias yao="yarn add --optional" +alias yad="yarn add --dev" +alias yl="yarn list --depth=0" +alias ylp="yarn list --depth=0 --pattern" +alias yu="yarn upgrade-interactive" + +alias ylg="yarn global list --depth=0" +alias ylgp="yarn global list --depth=0 --pattern" +alias yag="yarn global add" +alias yrg="yarn global remove" +alias yug="yarn global upgrade-interactive" + +alias ypub="yarn publish --access public" diff --git a/misc/less b/misc/less new file mode 100644 index 0000000..975ba70 --- /dev/null +++ b/misc/less @@ -0,0 +1,2 @@ +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" diff --git a/misc/prompt b/misc/prompt new file mode 100644 index 0000000..6da9535 --- /dev/null +++ b/misc/prompt @@ -0,0 +1,27 @@ +#!/bin/bash + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + + +# use http://bashrcgenerator.com/ +PARENTBASE='${PWD#"${PWD%/*/*}/"}' +PS1="\[\033[38;5;11m\]\u\[$(tput sgr0)\]@\h:\[$(tput sgr0)\]\[\033[38;5;6m\][\[$(tput sgr0)\]\[\033[38;5;14m\]${PARENTBASE}\[$(tput sgr0)\]\[\033[38;5;6m\]]\[$(tput sgr0)\]\[$(tput sgr0)\]" + +parse_git_branch() { + git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/' +} +PS1="$PS1\[\033[00m\]\$(parse_git_branch)\$ " diff --git a/misc/xterm b/misc/xterm new file mode 100644 index 0000000..9a97eec --- /dev/null +++ b/misc/xterm @@ -0,0 +1,5 @@ +#!/bin/bash +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm|xterm-color|*-256color) color_prompt=yes;; +esac diff --git a/modules/bind-mount/bind-mount.sh b/modules/bind-mount/bind-mount.sh new file mode 100755 index 0000000..fddd6c3 --- /dev/null +++ b/modules/bind-mount/bind-mount.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# must have fuser and bindfs installed +function bmount(){ + if [ "$1" == "-mp" ]; then + MOUNTED=$(mountpoint "$2" | grep not) + if [ -z "$MOUNTED" ]; then + echo $2 is a mount point so bind mounting $2/$3 to $4 + notify-send "bind mounting ${2}/${3} to ${4}" --icon=dialog-information -t 2000 + bindfs "$2/$3" "$4" + else + notify-send "${2} not a mount point - Unable to bind mount ${2}/${3} to ${4}" --icon=dialog-error -t 2000 + fi + else + echo bind mounting $1 to $2 + notify-send "bind mounting ${1} to ${2}" --icon=dialog-information -t 2000 + bindfs "$1" "$2" + fi +} + +function bumount(){ + echo "removing bind mount at $1" + notify-send "removing bind mount at ${1}" --icon=dialog-information -t 2000 + fusermount -u "$1" +} diff --git a/modules/editing/block/block.sh b/modules/editing/block/block.sh new file mode 100755 index 0000000..bc8b52b --- /dev/null +++ b/modules/editing/block/block.sh @@ -0,0 +1,147 @@ +#!/bin/bash + +BLOCK_FILE="" +BLOCK_NAME='BLOCK' +BLOCK_COMMENT_CHAR="#" +# a comment added before the block +BLOCK_DESCRIPTION="" + +function __update () { + if [ ! -z "$BLOCK_FILE" ]; then + touch $BLOCK_FILE + tail -c1 $BLOCK_FILE | read -r _ || echo >> $BLOCK_FILE + fi + BLOCK_BEGIN="$BLOCK_COMMENT_CHAR --- ${BLOCK_NAME} BEGIN ---" + BLOCK_END="$BLOCK_COMMENT_CHAR --- ${BLOCK_NAME} END ---" + BLOCK="\n$([ -z "$BLOCK_DESCRIPTION" ] || echo "${BLOCK_COMMENT_CHAR} ${BLOCK_DESCRIPTION}\n")${BLOCK_BEGIN}\n${BLOCK_END}" + # for testing + # BLOCK="a line before\n${BLOCK}\nanother line outside" + +} + +__update + # echo -e "default block template follows use: block-set before block-add to change>\n" $BLOCK + +function set-block () { + + declare OPTION + declare OPTARG + declare OPTIND + + while getopts ':f:c:d:n:' OPTION; do + echo $OPTION $OPTARG + case "$OPTION" in + f) + BLOCK_FILE=$OPTARG + echo File set to $BLOCK_FILE + ;; + c) + BLOCK_COMMENT_CHAR=$OPTARG + ;; + d) + BLOCK_DESCRIPTION=$OPTARG + ;; + n) + BLOCK_NAME=$OPTARG + ;; + *) + echo unknown option $OPTION + ;; + esac +done + +shift $(( OPTIND - 1 )) + +__update + echo -e "new block template follows use: block-add >\n" $BLOCK + echo ---- + echo $([ -e "$BLOCK_FILE" ] || echo "Warning: No output file set yet, use block-set -f " && echo "block will be placed in $BLOCK_FILE") + echo ------- +} + + +function add-block () { +# only add if it doesn't exist, existance is only based on block begin +local ADD +ADD=$(echo "${BLOCK}" | sed 's/\//\\\//g') +if [ -e "$BLOCK_FILE" ]; then +sed -n '/^[ \t]*'"${BLOCK_BEGIN}"'/{q50}' "${BLOCK_FILE}" +[ $? == 50 ] && return +WHERE=${1-${BLOCK_BEGIN}} # default is end +echo Where $WHERE +sed -i '/'"${WHERE}"'/{s/.*/&\n'"${ADD}"'/;h};${x;/^$/{s//'"$ADD"'/;H};x}' "${BLOCK_FILE}" +else + echo "no file set in which to add block, use: set-block -f " +fi +} + +modify-block () { + sed -i '/^'"${BLOCK_BEGIN}"'/,/^'"${BLOCK_END}"$'/ { + /'"${BLOCK_BEGIN}"'/b + /'"${BLOCK_END}"'/b + s/'"${1}"'/'"${2}"'/ + }' "${BLOCK_FILE}" +} + +remove-block () { + [ -z "$BLOCK_DESCRIPTION" ] || sed -ni '/'"${BLOCK_BEGIN}"'/{x;d;};1h;1!{x;p;};${x;p;}' "${BLOCK_FILE}" + remove-block-leading + sed -i '/^'"${BLOCK_BEGIN}"'/,/^'"${BLOCK_END}"$'/ { + d + }' "${BLOCK_FILE}" +} + +remove-block-leading () { + printf "%s\n" "$(tac $BLOCK_FILE \ + | sed '/'"${BLOCK_BEGIN}"'/,/^./{ /^[ \t]*$/d}' | tac)" > $BLOCK_FILE +} + +block-remove-content () { + sed -i '/^'"${BLOCK_BEGIN}"'/,/^'"${BLOCK_END}"$'/ { + /'"${BLOCK_BEGIN}"'/b + /'"${BLOCK_END}"'/b + d + }' "${BLOCK_FILE}" +} + + +block-add-line () { +# echo argument count $#, $1, $2, $3 +local ADD +ADD="/^${BLOCK_BEGIN}/a\\${1}" +if [ $# -gt 1 ]; then + if [ "$1" == "--end" ];then + ADD="/${BLOCK_END}/i\\${2}" +else + if [ "$1" == "--before" ];then + ADD="/${2}/i\\${3}" + else + ADD="/${1}/a\\${2}" + fi +fi +fi +# echo $ADD +sed -i '/^'"${BLOCK_BEGIN}"'/,/^'"${BLOCK_END}"$'/ { +'"${ADD}"' +}' "${BLOCK_FILE}" +} + +block-remove-line () { + sed -i '/^'"${BLOCK_BEGIN}"'/,/^'"${BLOCK_END}"$'/ { + /'"${1}"'/d + }' "${BLOCK_FILE}" +} + +block-change-line () { + sed -i '/^'"${BLOCK_BEGIN}"'/,/^'"${BLOCK_END}"$'/ { + /'"${1}"'/c\'"${2}"' + }' "${BLOCK_FILE}" +} + +block-modify-line () { + sed -i '/^'"${BLOCK_BEGIN}"'/,/^'"${BLOCK_END}"$'/ { + /'"${BLOCK_BEGIN}"'/b + /'"${BLOCK_END}"'/b + /'"${1}"'/{s/'"${2}"'/'"${3}"'/} + }' "${BLOCK_FILE}" +} diff --git a/modules/editing/block/test/test.sh b/modules/editing/block/test/test.sh new file mode 100755 index 0000000..4ae3972 --- /dev/null +++ b/modules/editing/block/test/test.sh @@ -0,0 +1,30 @@ +#!/bin/bash +rm test.txt +echo "some first text +some middle text +some after text" > test.txt +source ./block.sh +set-block -n "GO ENVIRONMENT" -d "comment before" +set-block -f "./test.txt" +# add-block "some middle text" +add-block +block-remove-content +block-add-line "1 added to beginning" +block-add-line --end "2 added to end" +block-add-line "3 yet another added to beginning" +block-add-line "4 yet yet another added to beginning -- remove later" +block-add-line --end "5 finally one added to end" +block-add-line ^2 "added after line 2" +block-add-line --before ^2 "added before line 2" +block-change-line "finally" "last line was changed to this" +echo modifying block +sleep 5 +block-modify-line "3" yet **yet** +modify-block added *added* +echo removing line with "remove" +sleep 5 +block-remove-line "remove" +echo "done with example, deleting" +sleep 5 +echo removing block now +remove-block diff --git a/modules/editing/replace/replace.sh b/modules/editing/replace/replace.sh new file mode 100755 index 0000000..cdbb08f --- /dev/null +++ b/modules/editing/replace/replace.sh @@ -0,0 +1,39 @@ +#!/bin/bash +function replace { + local PATTERN=$1; shift + local NEW_LINE=$1; shift + local FILE=$1; shift + [ ! "$PATTERN" ] || [ ! $FILE ] && return 1 + local BEFORE=$1 + local NEW=$(echo "${NEW_LINE}" | sed 's/\//\\\//g') + echo finding: $PATTERN Replace with $NEW before $BEFORE in $FILE + touch "${FILE}" || return 1 + echo matching: $PATTERN + match=false + if [ "$NEW_LINE" ]; then + sed -i '/'"${PATTERN}"'/{s/.*/'"${NEW}"'/;h};${x;/./{x;q100};{x;q20}}' "${FILE}" + [[ $? -eq 100 ]] && match=true + echo match $match + if [ $match == false ]; then + echo adding new entry $NEW_LINE + if [ "$BEFORE" ]; then + echo searching for $BEFORE to add line before + # sed -i '/'"${BEFORE}"'/{i/.*/'"${NEW}"'/;h};${x;/./{x;q100};x}' "${FILE}" + sed -i '/'"${BEFORE}"'/!{q20};/'"${BEFORE}"'/i\'"${NEW}" "${FILE}" + echo return $? + exit + # ;/i '"${NEW}"'' "${FILE}" + [[ $? -eq 100 ]] && match=true || match=false + echo before match $match + fi + # if [ $match == false ]; then + # echo appending to file + # echo "${NEW_LINE}" >> "${FILE}" + # fi + else echo line matched/replaced + fi + else + sed '/'"${PATTERN}"'/d' "${FILE}" + echo line removed + fi +} diff --git a/modules/editing/replace/replace.sh.save b/modules/editing/replace/replace.sh.save new file mode 100644 index 0000000..cdbb08f --- /dev/null +++ b/modules/editing/replace/replace.sh.save @@ -0,0 +1,39 @@ +#!/bin/bash +function replace { + local PATTERN=$1; shift + local NEW_LINE=$1; shift + local FILE=$1; shift + [ ! "$PATTERN" ] || [ ! $FILE ] && return 1 + local BEFORE=$1 + local NEW=$(echo "${NEW_LINE}" | sed 's/\//\\\//g') + echo finding: $PATTERN Replace with $NEW before $BEFORE in $FILE + touch "${FILE}" || return 1 + echo matching: $PATTERN + match=false + if [ "$NEW_LINE" ]; then + sed -i '/'"${PATTERN}"'/{s/.*/'"${NEW}"'/;h};${x;/./{x;q100};{x;q20}}' "${FILE}" + [[ $? -eq 100 ]] && match=true + echo match $match + if [ $match == false ]; then + echo adding new entry $NEW_LINE + if [ "$BEFORE" ]; then + echo searching for $BEFORE to add line before + # sed -i '/'"${BEFORE}"'/{i/.*/'"${NEW}"'/;h};${x;/./{x;q100};x}' "${FILE}" + sed -i '/'"${BEFORE}"'/!{q20};/'"${BEFORE}"'/i\'"${NEW}" "${FILE}" + echo return $? + exit + # ;/i '"${NEW}"'' "${FILE}" + [[ $? -eq 100 ]] && match=true || match=false + echo before match $match + fi + # if [ $match == false ]; then + # echo appending to file + # echo "${NEW_LINE}" >> "${FILE}" + # fi + else echo line matched/replaced + fi + else + sed '/'"${PATTERN}"'/d' "${FILE}" + echo line removed + fi +} diff --git a/modules/module.sh b/modules/module.sh new file mode 100644 index 0000000..d5a3ebe --- /dev/null +++ b/modules/module.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# shebang for syntax detection, not a command +# do *not* set executable! + +declare -Ag _modules_ + +shopt -s expand_aliases +alias _args_='(( $# ))' +alias _to_args_='set --' + +module.already_loaded () { + declare -Ag _modules_ + [[ -v _modules_[${BASH_SOURCE[1]}] ]] +} + +_blank_ () { + [[ -z ${1:-} ]] +} + +_defined_ () { + [[ -v $1 ]] +} + +_eq_ () { + [[ $1 == "${2:-}" ]] +} + +_functions_ () { + env -i bash </dev/null + compgen -A function;: +END +} + +_in_ () { + [[ $IFS$1$IFS == *"$IFS$2$IFS"* ]] +} + +_pop_ () { + local -n ref1=$1 + local ref2=${2:-} + + _present_ $ref2 && printf -v $ref2 %s "${ref1[-1]}" + unset -v $1[-1] +} + +_present_ () { + [[ -n ${1:-} ]] +} + +_push_ () { + local -n ref=$1 + + ref+=( "$2" ) +} + +_parent_=${BASH_SOURCE[1]:-} + +[[ ${1:-} != module ]] && return +set -- ${*:2} + +_numargs_+=( $# ) + +{ ! _args_ && _present_ ${_file_:-} && _eq_ $_parent_ $_file_ ;} && return + +{ ! _args_ && _present_ $_parent_ && ! _eq_ ${_parent_##*/} module ;} && { + _in_ "${_ancestors_[*]:-}" $_parent_ && return + _push_ _ancestors_ $_parent_ +} + +! _args_ && _to_args_ $_parent_ + +for _file_; do + _module_=${_file_%%=*} + _file_=${_file_#*=} + + _defined_ _modules_[$_file_] && continue + + _eq_ $_module_ $_file_ && { + _module_=${_module_##*/} + _module_=${_module_%.*} + } + + _prefixes_+=( $_module_ ) + + _push_ _aliases_ "$(alias)" + unalias -a + + _functions_=$(_functions_ $_file_) + + for _function_ in $_functions_; do + printf -v _prefix_ %s. ${_prefixes_[*]} + alias $_function_=$_prefix_$_function_ + done + + _push_ _files_ $_file_ + _push_ _funcs_ "$_functions_" + + set -- + source $_file_ + + unset -v _prefixes_[-1] + + _pop_ _files_ _file_ + _pop_ _funcs_ _functions_ + + _modules_[$_file_]='' + + for _function_ in $_functions_; do + unalias $_function_ + done + + eval "${_aliases_[-1]}" + _pop_ _aliases_ +done + +! (( ${#_files_[*]} )) && { + unalias _args_ + unalias _to_args_ + unset -f _blank_ + unset -f _defined_ + unset -f _eq_ + unset -f _in_ + unset -f _pop_ + unset -f _present_ + unset -f _push_ + unset -v _file_ + unset -v _funcs_ + unset -v _function_ + unset -v _functions_ + unset -v _module_ + unset -v _name_ + unset -v _parent_ + unset -v _prefix_ + unset -v _prefixes_ +} +{ ! (( _numargs_[-1] )) && [[ -n ${BASH_SOURCE[1]} && ${BASH_SOURCE[1]##*/} != module ]] ;} && unset -v _ancestors_[-1] +unset -v _numargs_[-1] + diff --git a/modules/modules.sh b/modules/modules.sh new file mode 100644 index 0000000..e381eea --- /dev/null +++ b/modules/modules.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# must have fuser and bindfs installed +module-load () { +BASH_MODULES="${BASH_MODULES:-/opt/bash/modules}" +MODULES=$1 +echo $MODULES +for i in ${MODULES[@]}; do + echo $BASH_MODULES ${i} + . "$BASH_MODULES"/"$i".sh +done +} diff --git a/modules/sshfs/sshfs.sh b/modules/sshfs/sshfs.sh new file mode 100755 index 0000000..38245d2 --- /dev/null +++ b/modules/sshfs/sshfs.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# depends on sshfs fuse for ssh +function smount(){ +MOUNTED=$(mountpoint "$2" | grep not) +if [ -z "$MOUNTED" ]; then + echo "remote $1 already mounted at $2, aborting mount" +else + echo "mounting $1 at $2 via ssh" + sshfs $1 $2 $3 $4 -o default_permissions +fi +} + +function usmount(){ +MOUNTED=$(mountpoint $1 | grep not) +if [ -z "$MOUNTED" ]; then + echo "unmounting remote file system at $1" + fusermount -u $1 +else + echo "nothing mounted at $1, aborting unmount" +fi +} + +DIR="${BASH_SOURCE%/*}" +if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi + +for f in $DIR/*; do +if [ ${f: -4} != ".off" ] && [ $(basename $f) != "sshfs.sh" ] && [ ! -d "$f" ] ; then +# echo 'loading mount functions for '$f +. $f +fi +done diff --git a/modules/usage b/modules/usage new file mode 100644 index 0000000..b69d567 --- /dev/null +++ b/modules/usage @@ -0,0 +1,6 @@ +BASH_MODULES="${BASH_MODULES:-/opt/bash/modules}" +. $BASH_MODULES/load-modules.sh +MODULES=(logit) +load-modules $MODULES + +logit v diff --git a/options b/options new file mode 100644 index 0000000..9a39225 --- /dev/null +++ b/options @@ -0,0 +1,20 @@ +#!/bin/bash +# append to the history file, don't overwrite it +shopt -s histappend +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# enable programmable completion features (you don't need to enable +# if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..8bb8e2d --- /dev/null +++ b/setup.sh @@ -0,0 +1,78 @@ +#!/bin/bash +DIR=${1:-$(dirname ${BASH_SOURCE[0]})} + +# source the required directory source function +if [ ! -e "$BASH_SHELL_BASE/source-dir.func" ]; then + echo "!Unable to load sourcing function at $DIR/source-dir, shell not set up!" +else + . $BASH_SHELL_BASE/source-dir.func + # source the default shopt options + [ -e "$DIR/options" ] && . $DIR/options + + function shell_process_directory () { + local SUBDIRS + local DIR + local DSUBDIRS + + DIR=${1:-$BASH_SHELL_BASE} + echo $DIR + + if [ -d "$DIR" ]; then + if [ "$DIR" = "$BASH_SHELL_BASE" ] && [ $BASH_SHELL_BASE_SOURCED ]; then + if [ -v PS1 ]; then + echo base directory already sourced + read -p "do you want to re-source the base (not recommended)? " -n 1 -r + echo + [[ ! $REPLY =~ ^[Yy]$ ]] && return 1 + else + return 1 + fi + fi + + if [ -f "$DIR/setup.sh" ] && [ "$DIR" != "$BASH_SHELL_BASE" ]; then + echo "$DIR/setup.sh" found, running instead of default processing + . "$DIR/setup.sh" + else + # default processing + local SUBDIRS + local DSUBDIRS + # default subdirectories to source + DSUBDIRS="env function alias misc lang app" + IFS=' ' read -r -a SUBDIRS <<< "${2:-$DSUBDIRS}" + # echo ${SUBDIRS[@]} + for SUBDIR in "${SUBDIRS[@]}" + do + if [ -e "$DIR/$SUBDIR" ]; then + echo processing subdirectory $DIR/$SUBDIR + # must quote all globs to avoid bash glob expansion which is likely on + source_dir -p "archive" -x '"*.off" "*.md"' -d 0 $DIR/$SUBDIR + else + echo no subdirectory $DIR/$SUBDIR to process, ignorning + fi + done + fi + echo "done sourcing directory $DIR" + else + echo $DIR does not exist nothing to source + fi + + + + } + +# process the base directory by default +unset BASH_SHELL_BASE_SOURCED +shell_process_directory +export BASH_SHELL_BASE_SOURCED=true +# process network +shell_process_directory "$BASH_SHELL_NETWORK/all" +[ $NETWORKNAME ] && shell_process_directory "$BASH_SHELL_NETWORK/$NETWORKNAME" +# process host +shell_process_directory "$BASH_SHELL_HOST/all" +shell_process_directory "$BASH_SHELL_HOST/$(hostname)" +# process user +# Note: $HOME/shell or $HOME/BASH_SHELL_USER are sourced via $HOME/.bashrc + +echo $(envg BASH) | xargs -n 1 + +fi diff --git a/source-dir.func b/source-dir.func new file mode 100644 index 0000000..265ae83 --- /dev/null +++ b/source-dir.func @@ -0,0 +1,109 @@ +#!/bin/bash +source_dir () { +# USAGE +# will never source source .files or .directories +# all option arguments that contain globs/wildcards must be quoted to avoid expansion +# p option excludes additional paths below of the given name (and depth) +# d option sets the directory depth which is current directy by default, 0 is all +# x excludes file globs +# f inclucdes only file globs otherwise it's all except .files +# if no directory is given it will attempt to source the present working directory +# example: +# source_dir -p "archive" -x '"*.off" "*.md"' -d 0 # $DIR/$SUBDIR +declare OPTION +declare OPTARG +declare OPTIND +local PATHS +local NAMES +local ENAMES +local DEPTH=1 +local VERBOSE=0 + +while getopts 'p:d:x:f:' OPTION; do +case "$OPTION" in + p) + # PATHS=("$OPTARG") + IFS=',' read -r -a PATHS <<< "$OPTARG" + # echo EXCLUDING THESE PATHS ${PATHS[*]} + ;; + x) + IFS=',' read -r -a ENAMES <<< "${OPTARG}" + # echo EXCLUDING THESE FILE NAMES ${ENAMES[*]} + ;; + f) + # NAMES=("$OPTARG") + IFS=',' read -r -a NAMES <<< "${OPTARG}" + # echo INCLUDING ONLY THESE FILE NAMES ${NAMES[*]} + ;; + d) + DEPTH=$OPTARG + # echo "SOURCING TO DEPTH (0=any)" "$DEPTH" + ;; + *) + echo unknown option $OPTION + ;; +esac +done + +shift $(( OPTIND - 1 )) + +local DIR +DIR="$@" +if [ ! "$DIR" ]; then + if [ -v PS1 ]; then + echo no directory to source provided + echo sourcing present working directory $(pwd) + read -p "Do you want to continue? " -n 1 -r + [[ $REPLY =~ ^[Yy]$ ]] && DIR=$(pwd) || return 1 + else + return 1 + fi +fi + +[ ! -d "$DIR" ] && echo " directory $DIR does not exist, aborting" && return 1 + +# echo dir $DIR + +local FIND +FIND="find $DIR" +FIND+=$([ ! $DEPTH == 0 ] && echo " -maxdepth $DEPTH ") +FIND+=" -type f ! -path \"*/.*/*\" ! -name \".*\" " + + +local name +local path + +if [[ ${PATHS[0]} ]]; then + for path in ${PATHS[@]}; do + # echo excluding $path + FIND+=$(echo ' ! -path "*/'$path'/*"') + done +fi + +if [[ ${ENAMES[0]} ]]; then + for name in ${ENAMES[@]}; do + # echo excluding name $name + FIND+=$(echo " ! -name ${name}") + done +fi + +if [[ ${NAMES[0]} ]]; then + for name in ${NAMES[@]}; do + # echo only finding $name + FIND+=$(echo " -name ${name}") + done +fi + +# echo +# echo find dir: $DIR +# echo find command: $FIND + +local FILES +FILES=$(eval $FIND | sort) +# echo $FILES | xargs -n 1 + for f in $FILES; do + # echo sourcing: $f + . "$f" +done + +}