e1e0.net

sources for e1e0 website
git clone https://git.e1e0.net/e1e0.net.git
Log | Files | Refs

aliases-helper-functions-shell.md (11202B)


      1 Title: Aliases and helper functions for the shell
      2 Author: paco
      3 Date: 2020-07-03
      4 Type: article
      5 
      6 This is a compilation of shell aliases and helper functions I found useful and
      7 use more or less regularly.  Some of them are of my creation and some have been
      8 stolen and adapted over the years.
      9 It's not a complete list.  Just the ones that I think might be useful to
     10 somebody else.
     11 
     12 This comes from a [toot from pamela@][1], and I thought to put it here to be
     13 more permanent.
     14 
     15 I use `zsh` on my machines as interactive shell, but I guess this can be used
     16 with little to no modification on other shells.
     17 I also use `tmux(1)` heavily.
     18 
     19 ## Basic aliases
     20 
     21 First some basic aliases (comments in line):
     22 
     23 ```
     24 # create a tmux split 82 columns wide, used to take a peek at man pages
     25 alias tman='tmux split-window -h -l 82 man'
     26 ```
     27 
     28 _Update 2021-05-01:_ Reader Chang, Chu-Kuan sends me a variation of this last
     29 one that does not require you to have a _free_ terminal to invoke it.  It's
     30 basically the same but with a `tmux(1)` bind key.  This should go in your
     31 `.tmux.conf`:
     32 
     33 ```
     34 bind-key M command-prompt -I 'split-window -h -l 82 man '
     35 ```
     36 
     37 And now, more aliases:
     38 
     39 ```
     40 # I use kubernetes at work, so those save a lot of typing.
     41 # I also use some custom subcommands, via kubectl plugins.  I might write about
     42 # that ...
     43 if command -v kubectl > /dev/null ; then
     44     alias k='kubectl'
     45     alias kg='kubectl get'
     46     alias kgdep='kubectl get deployment'
     47     alias kgsvc='kubectl get service'
     48     alias kging='kubectl get ingress'
     49     alias kgcm='kubectl get configmap'
     50     alias kgsec='kubectl get secret'
     51     alias kd='kubectl describe'
     52     alias ka='kubectl apply -f'
     53     alias krm='kubectl delete'
     54     alias kex='kubectl exec -i -t'
     55     alias kedep='kubectl edit deployment'
     56     alias kecm='kubectl edit configmap'
     57     alias ktopn='kubectl top node'
     58 fi
     59 
     60 # also for work, google cloud sdk stuff ...
     61 if command -v gcloud > /dev/null ; then
     62     alias gcil='gcloud compute instances list'
     63     alias gcssh='TERM=screen-256color gcloud compute ssh'
     64     alias gcscp='gcloud compute scp'
     65     # those 2 are specially useful, to sync the context change
     66     # for Google cloud project and kubernetes cluster
     67     alias Sprod='kubectl config use-context prod; gcloud config configurations activate prod'
     68     alias Sstg='kubectl config use-context stg; gcloud config configurations activate default'
     69 fi
     70 
     71 # I always forget to use doas with pkg_* commands.  Also, set -Dsnap which
     72 # never hurts
     73 if command -v pkg_add > /dev/null; then
     74     for c in add delete check; do
     75         alias pkg_${c}="doas /usr/sbin/pkg_${c} -Dsnap"
     76     done
     77     alias pkg_info="/usr/sbin/pkg_info -Dsnap"
     78 fi
     79 ```
     80 
     81 ## Named directories
     82 
     83 I also make some heavy use of named directories in `zsh`.  This is probably not
     84 present on other shells.
     85 
     86 The thing is that I can refer to common used folders by a short name, like
     87 `~se` for `$HOME/src/git.e1e0.net` and things like that.  And they work
     88 anywhere on the command line. Here some examples:
     89 
     90 ```
     91 test -d $HOME/src && hash -d s=$HOME/src
     92 test -d $HOME/src/git.e1e0.net && hash -d se=$HOME/src/git.e1e0.net
     93 test -d /mnt/nas/fotos && hash -d f=/mnt/nas/fotos
     94 ...
     95 ```
     96 
     97 ## Helper functions
     98 
     99 The next bits are for interacting with my [transmission][2] server at home.
    100 I never remember the options and stuff, so this covers the basic operations:
    101 
    102 ```
    103 # list torrents
    104 alias trls='transmission-remote my.transmission.host --authenv -l'
    105 
    106 # remove a torrent from the list (-d deletes the downloaded files too)
    107 function trrm () {
    108     if [[ "$1" == "-d" ]]; then
    109         action="--remove-and-delete"
    110         torrent="$2"
    111     else
    112         action="--remove"
    113         torrent="$1"
    114     fi
    115     transmission-remote my.transmission.host --authenv -t $torrent $action
    116 }
    117 
    118 # clean all torrents from the queue
    119 function trclean() {
    120     for i in $(transmission-remote my.transmission.host --authenv -l | awk '$2=="100%" {print $1}')
    121     do
    122         if [[ "$1" == "-d" ]]; then
    123             action="--remove-and-delete"
    124         else
    125             action="--remove"
    126         fi
    127         transmission-remote my.transmission.host --authenv -t $i $action
    128     done
    129 }
    130 ```
    131 
    132 For adding torrents I use a python script so I can put them more or less
    133 automatically in folders to organize them, but that's a bit more complicated.
    134 
    135 Some temperature conversion helpers (not used every day, but nice to have):
    136 
    137 ```
    138 # temperature conversion
    139 function c2f() {
    140     F=$(printf "scale=2\n$1 *  1.80 + 32\n" | bc)
    141     printf "C: $1\nF: $F\n"
    142 }
    143 
    144 function f2c() {
    145     C=$(printf "scale=2\n($1 -32)/1.80\n" | bc)
    146     printf "F: $1\nC: $C\n"
    147 }
    148 # for everything else, use units(1)
    149 ```
    150 
    151 This one is pretty useful, as my ISP changes my public IP regularly.
    152 
    153 ```
    154 # What is my External IP
    155 function myip() { printf "External IP: %s\n" $(curl -s -4 http://ifconfig.co/) ;}
    156 ```
    157 
    158 Small random ones (commented in place):
    159 
    160 ```
    161 # quick and dirty file backup.
    162 function bak() {
    163     cp -v ${1}{,.bak}
    164 }
    165 
    166 # replace all spaces by underscore (only for zsh)
    167 function mvsp() {
    168     autoload -U zmv
    169     zmv '* *' '$f:gs/ /_'
    170 }
    171 
    172 # Grep the history with 'h'
    173 function h () {
    174     if command -v rg > /dev/null 2>&1
    175     then
    176         mycommand=rg
    177     else
    178         mycommand=grep
    179     fi
    180 
    181     history 0 | $mycommand $1
    182 }
    183 
    184 # weather forecast on the terminal.  Just fantastic.
    185 function wf () {
    186     CITY=$1
    187     if [[ -z "$CITY" ]]; then
    188         CITY="MyCity"
    189     fi
    190     curl wttr.in/${CITY}
    191 }
    192 
    193 # function to copy main ssh keys to clipboard when needed.
    194 function pubkey () {
    195     ssh-add -L |grep 'cardno:000000000000' |\
    196       xclip -f -selection clipboard
    197     echo "=> Public key copied to clipboard."
    198 }
    199 
    200 # Neat trick from https://github.com/lf94/peek-for-tmux/blob/master/README.md
    201 # temporary tmux split (1/3 of the window) to look into some file
    202 function peek() {
    203     tmux split-window -p 33 less $@ || exit;
    204 }
    205 ```
    206 
    207 This one I use quite a bit.  It's my personal _pastebin_:
    208 
    209 ```
    210 # poor man's pastebin service (and secure !)
    211 function pb() {
    212     filename="$1"
    213     dest=""
    214     if [[ -z "$filename" ]]; then
    215         dest=$(tr -cd '[:alnum:]' < /dev/urandom |dd bs=1 count=8 2>/dev/null)
    216         ssh w1.e1e0.net "cat > /var/www/pastes/$dest"
    217     else
    218         dest=$(basename "$filename")
    219         scp -q "$filename" "w1.e1e0.net:/var/www/pastes/$dest"
    220     fi
    221     echo -n "https://e1e0.net/paste/$dest" |\
    222         xclip -f -selection clipboard
    223     echo ''
    224 }
    225 ```
    226 
    227 It can be used like `echo foo | pb` or `pb myfile.txt` and will produce
    228 a unique URL if no file name is provided.
    229 
    230 And a shortcut and dispatcher for `git`.  `g` executes `git status -s` and
    231 everything else is just passed to `git` as is.
    232 
    233 ```
    234 function g() {
    235     if (( $# == 0 )); then
    236         git status -s
    237     else
    238         git "$@"
    239     fi
    240 }
    241 ```
    242 
    243 ## OpenBSD ports stuff.
    244 
    245 And now the ports stuff.  All this is probably overkill, but I use them all the
    246 time while working with ports.
    247 
    248 As the comment at the top says this is totally stolen from other devs.  I can't
    249 remember what's from who, I probably took bits and pieces from their public
    250 dot files and just adapted it to my needs.
    251 
    252 Basically this is a dispatcher function `p`.  It composes the name of the
    253 function to call.  If it exists it's called, if not the `_port-doas` function
    254 is called.  This is useful as I use `PORTS_PRIVSEP=Yes` so everything in ports
    255 belongs to the user `_pbuild`.
    256 
    257 Some functions make use of external commands like _danj@_'s `show-victims`
    258 (this is actually a rewrite I did in Go, the original in Python) to look for
    259 consumers of a port, or _juanfra@_'s `outdated-packages.py` to query
    260 [portroach][3].  The latter is pretty useful for _"port fishing"_.  Remember
    261 folks, there are a lot of outdated ports without maintainer !
    262 
    263 ```
    264 # ports stuff
    265 # shamelessly stolen from Klemens Nanni (kn@), Daniel Jakots (danj@)
    266 # and Solene Rapenne (solene@)
    267 
    268 p() {
    269     [ $# -gt 0 ] || return
    270     if typeset -f \_port-"$1" > /dev/null; then
    271         _port-"$@"
    272     else
    273         _port-doas "$@"
    274     fi
    275 }
    276 
    277 function _port-search() {
    278     local pt="/usr/ports"
    279 
    280     [[ -z ${1} ]] && echo "Need a keyword to search for" && return
    281     [[ ! -d ${pt} ]] && echo "Cannot find ports tree" && return
    282 
    283     cd ${pt} && make search name=${1}
    284     cd -
    285 }
    286 function _port-s() { \_port-search "$@" }
    287 
    288 function _port-sql() { sqlite3 /usr/local/share/sqlports }
    289 function _port-pldc() { make port-lib-depends-check }
    290 function _port-ldc() { make lib-depends-check }
    291 function _port-pdf() {
    292     if command -v cdiff > /dev/null ; then
    293         diff -up pkg/PLIST.orig pkg/PLIST | cdiff
    294     else
    295         diff -up pkg/PLIST.orig pkg/PLIST | less
    296     fi
    297 }
    298 function _port-src() { cd `make show=WRKSRC` }
    299 function _port-clean() { make clean=all }
    300 
    301 function _port-diff()
    302 {
    303     if [[ -d /usr/ports/.got/ ]]; then
    304         got diff > /usr/ports/mystuff/${PWD##*/}.diff
    305     else
    306         cvs diff > /usr/ports/mystuff/${PWD##*/}.diff
    307     fi
    308     if command -v cdiff > /dev/null ; then
    309         cdiff /usr/ports/mystuff/${PWD##*/}.diff
    310     else
    311         less /usr/ports/mystuff/${PWD##*/}.diff
    312     fi
    313 }
    314 function _port-df() { \_port-diff "$@" }
    315 
    316 function _port-lessdiff() {
    317     if command -v cdiff > /dev/null ; then
    318         cdiff /usr/ports/mystuff/${PWD##*/}.diff
    319     else
    320         less /usr/ports/mystuff/${PWD##*/}.diff
    321     fi
    322 }
    323 function _port-ldf() { \_port-lessdiff "$@" }
    324 
    325 function _port-pygrep() { rg $@ --type make --glob '!*mystuff*' --glob '!lost+found' /usr/ports/*/py-* }
    326 
    327 function _port-f() { \_port-find "$@" }
    328 function _port-find() { rg -i $@ /usr/local/share/sqlports.list }
    329 
    330 function _port-grep() { rg $@ --type make --glob '!*mystuff*' --glob '!lost+found' /usr/ports }
    331 
    332 function _port-update() {
    333     local current_dir=$(pwd)
    334     if [[ -d /usr/ports/.got ]]; then
    335         cd /var/git/ports.git/ && git fetch origin master:master
    336         cd /usr/ports && got update -b master
    337         cd "$current_dir"
    338     else
    339         cd /usr/ports && cvs -q up -Pd -A && cd "$current_dir"
    340     fi
    341 }
    342 function _port-up() { \_port-update "$@" }
    343 
    344 function _port-lessmake() { less "/usr/ports/$1/Makefile" }
    345 function _port-lmk() { \_port-lessmake "$@" }
    346 
    347 function _port-doas() {
    348     command doas -u _pbuild "$@"
    349 }
    350 
    351 function _port-help() {
    352     # (k) returns only the keys from associative array.  Look zshexpn(1)
    353     printf "%s\n" "${(k)functions[@]}" | sort | grep "^_port-" | sed 's/_port-//'
    354 }
    355 
    356 function _port-ou() { \_port-outdated "$@" }
    357 function _port-outdated() {
    358     if [ ! -x "$HOME/bin/outdated-packages.py" ]; then
    359         echo "Cannot find script" >&2 && return
    360     fi
    361     "$HOME/bin/outdated-packages.py" "$@"
    362 }
    363 
    364 function _port-sv() { \_port-showvictims "$@" }
    365 function _port-showvictims() {
    366     if [ ! -x "$HOME/bin/port-showvictims" ]; then
    367         echo "Cannot find executable" >&2 && return
    368     fi
    369     "$HOME/bin/port-showvictims" "$@"
    370 }
    371 
    372 function _port-patch {
    373     local level=${2:-0}
    374     patch -E -C -p$level < $1 && patch -E -p$level < $1
    375     echo $?
    376 }
    377 
    378 alias py3='env FLAVOR=python3 '
    379 
    380 function cvsdiff() {
    381     if command -v cdiff > /dev/null ; then
    382         cvs diff $@ | cdiff
    383     else
    384         cvs diff $@ | less
    385     fi
    386 }
    387 ```
    388 
    389 And that's basically it.  I hope is useful for somebody.
    390 
    391 [1]: https://bsd.network/@pamela/104370718366426100
    392 [2]: https://transmissionbt.com/
    393 [3]: https://portroach.openbsd.org/