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/