#+TITLE: .profile #+AUTHOR: Mitch Tishmack #+STARTUP: hidestars #+STARTUP: odd #+BABEL: :cache yes #+PROPERTY: header-args :cache yes #+PROPERTY: header-args :padline no #+PROPERTY: header-args :mkdirp yes #+PROPERTY: header-args :comments no #+PROPERTY: header-args :replace yes #+PROPERTY: header-args :tangle tmp/.profile ~/.profile setup in all its peculiarities. * PS1 #+BEGIN_SRC sh # -*- mode: Shell-script; -*- # Common .profile # # DO NOT EDIT, managed by org mode _uname=$(uname) _uname_n=$(uname -n) _hostname=$(hostname) export _uname _uname_n _hostname #+END_SRC OSX uses hostname -s for getting hostname #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p macos-p)) _host=$(hostname -s) #+END_SRC Otherwise we just use what uname -n sent. #+BEGIN_SRC sh _host=${_host:=${_uname_n}} #+END_SRC * PATH ** haskell #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p haskell-p)) PATH="${PATH}:${HOME}/.cabal/bin" #+END_SRC * Functions ** General Generally useful functions. #+BEGIN_SRC sh # cat out a : separated env variable # variable is the parameter cat_env() { set | grep '^'"$1"'=' > /dev/null 2>&1 && eval "echo \$$1" | tr ':' ' ' | awk '!/^\s+$/' | awk '!/^$/' } # Convert a line delimited input to : delimited to_env() { awk '!a[$0]++' < /dev/stdin | tr -s ' ' ':' | sed -e 's/\:$//' | awk 'NF > 0' } # Unshift a new value onto the env var # first arg is ENV second is value to unshift # basically prepend value to the ENV variable unshift_env() { new=$(eval "echo $2; echo \$$1" | to_env) eval "$1=${new}; export $1" } # Opposite of above, but echos what was shifted off shift_env() { first=$(cat_env "$1" | head -n 1) rest=$(cat_env "$1" | awk '{if (NR!=1) {print}}' | to_env) eval "$1=$rest; export $1" echo "${first}" } # push $2 to $1 on the variable push_env() { have=$(cat_env "$1") new=$(printf "%s %s" "$have" "$2" | to_env) eval "$1=$new; export $1" } # Remove a line matched in $HOME/.ssh/known_hosts for when there are legit # host key changes. nukehost() { if [ -z "$1" ]; then echo "Usage: nukehost " echo " Removes from ssh known_host file." else sed -i -e "/$1/d" ~/.ssh/known_hosts fi } # Cheap copy function to make copying a file via ssh from one host # to another less painful, use pipeviewer to give some idea as to progress. sshcopy() { if [ -z "$1" -o -z "$2" ]; then echo "Usage: copy source:/file/location destination:/file/location" else srchost="$(echo "$1" | awk -F: '{print $1}')" src="$(echo "$1" | awk -F: '{print $2}')" dsthost="$(echo "$2" | awk -F: '{print $1}')" dst="$(echo "$2" | awk -F: '{print $2}')" size=$(ssh "$srchost" du -hs "$src" 2> /dev/null) if [ "${size}" = "" ]; then echo "${src} doesn't seem to exist on ${srchost}" return 1 fi size=$(echo "${size}" | awk '{print $1}') echo "Copying $size to $dst" (ssh "$srchost" "/bin/cat $src" | pv -cb -N copied - | ssh "$dsthost" "/bin/cat - > $dst") 2> /dev/null fi } # extract function to automate being lazy at extracting archives. extract() { if [ -f "$1" ]; then case ${1} in *.tar.bz2|*.tbz2|*.tbz) bunzip2 -c "$1" | tar xvf -;; *.tar.gz|*.tgz) gunzip -c "$1" | tar xvf -;; *.tz|*.tar.z) zcat "$1" | tar xvf -;; *.tar.xz|*.txz|*.tpxz) xz -d -c "$1" | tar xvf -;; *.bz2) bunzip2 "$1";; *.gz) gunzip "$1";; *.jar|*.zip) unzip "$1";; *.rar) unrar x "$1";; *.tar) tar -xvf "$1";; *.z) uncompress "$1";; *.rpm) rpm2cpio "$1" | cpio -idv;; *) echo "Unable to extract <$1> Unknown extension." esac else print "File <$1> does not exist." fi } # Tcsh compatibility so I can be a lazy bastard and paste things directly # if/when I need to. setenv() { export "$1=$2" } # Just to be lazy, set/unset the DEBUG env variable used in my scripts debug() { if [ -z "$DEBUG" ]; then if [ -z "$1" ]; then echo Setting DEBUG to "$1" setenv DEBUG "$1" else echo Setting DEBUG to default setenv DEBUG default fi else echo Unsetting DEBUG unset DEBUG fi } login_shell() { [ "$-" = "*i*" ] } # Yeah, sick of using the web browser for this crap # Use is NUM FROM TO and boom get the currency converted from goggle. cconv() { curl -L --silent\ "https://www.google.com/finance/converter?a=$1&from=$2&to=$3" \ | grep converter_result \ | perl -pe 's|[<]\w+ \w+[=]\w+[>]||g;' -e 's|[<][/]span[>]||' } #+END_SRC ** git General clone into ~/src/TLD/some/dir from a git uri function. Tries to strip out miscellany that we don't need from the uri. Also allows wrapper functions that simplify usage. Note the gh and bb wrappers which make it easy to get repos from github and bitbucket. Usage is simply: try_git some_uri optional_branch_if_not_master The gh wrapper wraps this and simplifies usage by setting up the uri as https so we can do the following example: gh user/repo maybe_branch This checks out something from https://github.com/user/repo.git to ~/src/github.com/user/repo This also makes for a somewhat easy way to cd into the dir as well without push/popd. The bb wrapper behaves the same. Presuming using the bare try_git function, the dir in ~/src/TLD is simply what comes after the tld. Example: try_git git://example.tld/some/random/path.git checks out to ~/src/example.tld/some/random/path #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p git-p)) try_git() { # assume https if input doesn't contain a protocol proto=https destination=${HOME}/src branch="${2:-master}" echo "${1}" | grep '://' > /dev/null 2>&1 [ $? = 0 ] && proto=$(echo "${1}" | sed -e 's|[:]\/\/.*||g') git_dir=$(echo "${1}" | sed -e 's|.*[:]\/\/||g') rrepo="${proto}://${git_dir}" # strip user@, :NNN, and .git from input uri's repo="${destination}/"$(echo "${git_dir}" | sed -e 's/\.git$//g' | sed -e 's|.*\@||g' | sed -e 's|\:[[:digit:]]\{1,\}\/|/|g' | tr -d '~') if [ ! -d "${repo}" ]; then if git ls-remote "${rrepo}" > /dev/null 2>&1; then mkdir -p "${repo}" echo "git clone ${rrepo} ${repo}" git clone --recursive "${rrepo}" "${repo}" else echo "${rrepo} doesn't look to be a git repository" fi fi if [ "${branch}" != "master" ]; then wtdir="${repo}@${branch}" if [ -d "${wtdir}" ]; then cd "${wtdir}" else if git branch -r --list 'origin/*' | grep -E "^\s+origin/${branch}$" > /dev/null 2>&1; then git worktree add ${repo}@${branch} ${branch} && cd "${wtdir}" fi fi else [ -d "${repo}" ] && cd "${repo}" fi } gh() { try_git "https://github.com/${1}" "${2:-master}" } bb() { try_git "https://bitbucket.org/${1}" "${2:-master}" } #+END_SRC ** haskell #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p haskell-p)) hmap() { ghc -e "interact ($*)" } hmapl() { hmap "unlines.($*).lines" } hmapw() { hmapl "map (unwords.($*).words)" } #+END_SRC ** nix #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p nix-p)) mk_nix_shell() { cabal2nix --sha256="0" . \ | perl -0777 -p -e 's/{.+}:/{ haskellPackages ? (import {}).haskellPackages }:/s' \ | sed -E -e 's/(cabal\.mkDerivation)/with haskellPackages; \1/' -e 'sXsha256 = "0";Xsrc = "./.";X' \ > shell.nix; } # TODO: any of this useful to keep around? nr() { nix-shell --run "$(echo $@)" } nix-on() { rm ~/.nonix } nix-off() { touch ~/.nonix } #+END_SRC Workaround stupid ssl crap with recent nix. #+BEGIN_SRC sh :tangle (tangle/file ".profile" (and (bound-and-true-p nix-p) (bound-and-true-p macos-p))) if [ ! -e ${HOME}/.nonix ]; then SSL_CERT_FILE="${HOME}/.nix-profile/etc/ssl/certs/ca-bundle.crt" GIT_SSL_CAINFO=$SSL_CERT_FILE export SSL_CERT_FILE export GIT_SSL_CAINFO fi #+END_SRC The nix installer adds this which I don't want, $HOME is fully prefixed in what is added. #+BEGIN_SRC sh :tangle no if [ -e $HOME/.nix-profile/etc/profile.d/nix.sh ]; then . $HOME/.nix-profile/etc/profile.d/nix.sh # added by Nix installer #+END_SRC #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p nix-p)) if [ ! -e ${HOME}/.nonix ] && [ -e ~/.nix-profile/etc/profile.d/nix.sh ]; then source ~/.nix-profile/etc/profile.d/nix.sh fi #+END_SRC TODO Add linux ca-bundle detection if test -e /etc/ssl/certs/ca-bundle.crt ; # Fedora, NixOS set -xg SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt ; else if test -e /etc/ssl/certs/ca-certificates.crt ; # Ubuntu, Debian set -xg SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt ** tmux #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p tmux-p)) t() { if [ -z "$1" ]; then echo "Supply a tmux session name to connect to/create" else tmux has-session -t "$1" 2>/dev/null [ $? != 0 ] && tmux new-session -d -s "$1" tmux attach-session -d -t "$1" fi } #+END_SRC ** x #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p x-p)) modmap() { [ -f "${HOME}/.Xmodmap" ] && xmodmap "${HOME}/.Xmodmap" } #+END_SRC * Aliases ** General #+BEGIN_SRC sh # general aliases alias s="\$(which ssh)" alias quit='exit' alias cr='reset; clear' alias a=ag alias n=noglob alias l=ls alias L='ls -dal' alias cleandir="find . -type f \( -name '*~' -o -name '#*#' -o -name '.*~' -o -name '.#*#' -o -name 'core' -o -name 'dead.letter*' \) | grep -v auto-save-list | xargs -t rm" # Prefer less for paging duties. which less > /dev/null 2>&1 if [ $? -eq 0 ]; then alias T="\$(which less) -f +F" else alias T="\$(which tail) -f" fi alias e=emacs alias de=emacs --debug-init -nw alias ec=emacsclient alias ect=emacsclient -t alias oec=emacsclient -n -c alias stope=emacsclient -t -e "(save-buffers-kill-emacs)(kill-emacs)" alias kille=emacsclient -e "(kill-emacs)" #+END_SRC ** osx #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p macos-p)) alias o='open -a' #+END_SRC ** git #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p git-p)) alias g=git #+END_SRC ** haskell #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p haskell-p)) alias ghce="ghc -e ':l ~/.ghc.hs' -e" #+END_SRC ** mosh #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p mosh-p)) alias m=mosh #+END_SRC ** tmux #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p tmux-p)) alias tl='tmux ls' #+END_SRC * Final PATH #+BEGIN_SRC sh :tangle "tmp/.profile" PATH="${PATH}:${HOME}/bin:${HOME}/.local/bin" export PATH #+END_SRC * cray Cray specific stuff. Note the stash function uses the wrapper to try for project/repo first, and iff that fails then tries for the input a second time as user/repo. #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p cray-p)) stash() { try_git "ssh://git@stash.us.cray.com:7999/${1}.git" "${2:-master}" || \ try_git "ssh://git@stash.us.cray.com:7999/~${1}.git" "${2:-master}" } stopit () { sudo pkill -fai -P1 microsoft sudo pkill -fai -P1 ntpd sudo killall Python sudo killall java } # Every week check to see if ad password will be close to expiring. if [ -e ~/.password ]; then pfile=~/.password last=$(cat ${pfile}) now=$(date +%s) if [ $(( (now - last) > (60*60*24*7) )) -ne 0 ]; then ~/bin/adexpire echo "${now}" > ${pfile} fi fi # wats() # { # eval $(ioreg -n AppleSmartBatteryManager -r -l | grep -iE '\"(Voltage|InstantAmperage)\" =' | tr -d '"' | tr -d " ") # printf "~ %.2f watts\n" $(( (Voltage/1000.0) * (InstantAmperage/1000.0) )) # } # eval $(system_profiler SPPowerDataType | grep -iE 'Amperage|Voltage' | sed -e 's| [(]m[AV][)][:] |=|g' | tr -d '-') # printf "~ %.2f watts\n" $(( (Voltage/1000.0) * (Amperage/1000.0) )) chkupdate() { (sudo softwareupdate --list --all & /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate --list & wait ) } updateitall() { (sudo softwareupdate --install --all --include-config-data /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate --install & wait ) } # os_token() # { # token_sh=$(openstack token issue -c id -c project_id -f shell) # os_rc=$? # token_eval=$(echo "${token_sh}" | sed -e 's|project_id=|export OS_PROJECT_ID=|' -e 's|id=|export OS_TOKEN=|') # # strip out OS_ vars we don't want exposed any longer, force auth to using tokens # if [ $os_rc ] ; then # eval "$token_eval" # export OS_AUTH_TYPE=token # unset OS_PASSWORD # unset OS_USER_DOMAIN_NAME # else # printf "nope %s rc: $d" "$token_sh" "$os_rc" >&2 # fi # } #+END_SRC Ldapsearch aliases to make it easier to poke around in ldap. NOTE: most of these examples are just using filters on data in ldap they also presume you're on the relevant vpn dump out a specific user in the cray ldap cray "(sAMAccountName=$USER)" examples: Get a managers employee number in hpe ldap hpe "(cn=*eter*ojanic)" cn employeeNumber Then get all the email addresses of their reports hpe "(managerEmployeeNumber=35016016)" cn mail #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p cray-p)) alias cray='LDAPTLS_REQCERT=never ldapsearch -ZZ -x -h cfdc01.us.cray.com -b "OU=Users,OU=Cray Objects,DC=americas,DC=cray,DC=com" -s sub' alias hpe='ldapsearch -LLL -x -H ldaps://hpe-pro-ods-ed.infra.hpecorp.net -b o=hp.com' #+END_SRC silly functions to make using k8s in minikube a bit less annoying #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p cray-p)) mk() { if [ $1 = "kubectl" ]; then shift; echo minikube kubectl -- $* minikube kubectl -- $* else echo minikube $* minikube $* fi } #+END_SRC #+BEGIN_SRC sh :tangle (tangle/file ".profile" (bound-and-true-p cray-p)) fixpock() { close Pock open -a Pock } leaving() { fixpock hdiutil eject /Volumes/backup } #+END_SRC