Aliases and helper functions for the shell
2020-07-03
This is a compilation of shell aliases and helper functions I found useful and use more or less regularly. Some of them are of my creation and some have been stolen and adapted over the years. It's not a complete list. Just the ones that I think might be useful to somebody else.
This comes from a toot from pamela@, and I thought to put it here to be more permanent.
I use zsh
on my machines as interactive shell, but I guess this can be used
with little to no modification on other shells.
I also use tmux(1)
heavily.
Basic aliases
First some basic aliases (comments in line):
# create a tmux split 82 columns wide, used to take a peek at man pages
alias tman='tmux split-window -h -l 82 man'
Update 2021-05-01: Reader Chang, Chu-Kuan sends me a variation of this last
one that does not require you to have a free terminal to invoke it. It's
basically the same but with a tmux(1)
bind key. This should go in your
.tmux.conf
:
bind-key M command-prompt -I 'split-window -h -l 82 man '
And now, more aliases:
# I use kubernetes at work, so those save a lot of typing.
# I also use some custom subcommands, via kubectl plugins. I might write about
# that ...
if command -v kubectl > /dev/null ; then
alias k='kubectl'
alias kg='kubectl get'
alias kgdep='kubectl get deployment'
alias kgsvc='kubectl get service'
alias kging='kubectl get ingress'
alias kgcm='kubectl get configmap'
alias kgsec='kubectl get secret'
alias kd='kubectl describe'
alias ka='kubectl apply -f'
alias krm='kubectl delete'
alias kex='kubectl exec -i -t'
alias kedep='kubectl edit deployment'
alias kecm='kubectl edit configmap'
alias ktopn='kubectl top node'
fi
# also for work, google cloud sdk stuff ...
if command -v gcloud > /dev/null ; then
alias gcil='gcloud compute instances list'
alias gcssh='TERM=screen-256color gcloud compute ssh'
alias gcscp='gcloud compute scp'
# those 2 are specially useful, to sync the context change
# for Google cloud project and kubernetes cluster
alias Sprod='kubectl config use-context prod; gcloud config configurations activate prod'
alias Sstg='kubectl config use-context stg; gcloud config configurations activate default'
fi
# I always forget to use doas with pkg_* commands. Also, set -Dsnap which
# never hurts
if command -v pkg_add > /dev/null; then
for c in add delete check; do
alias pkg_${c}="doas /usr/sbin/pkg_${c} -Dsnap"
done
alias pkg_info="/usr/sbin/pkg_info -Dsnap"
fi
Named directories
I also make some heavy use of named directories in zsh
. This is probably not
present on other shells.
The thing is that I can refer to common used folders by a short name, like
~se
for $HOME/src/git.e1e0.net
and things like that. And they work
anywhere on the command line. Here some examples:
test -d $HOME/src && hash -d s=$HOME/src
test -d $HOME/src/git.e1e0.net && hash -d se=$HOME/src/git.e1e0.net
test -d /mnt/nas/fotos && hash -d f=/mnt/nas/fotos
...
Helper functions
The next bits are for interacting with my transmission server at home. I never remember the options and stuff, so this covers the basic operations:
# list torrents
alias trls='transmission-remote my.transmission.host --authenv -l'
# remove a torrent from the list (-d deletes the downloaded files too)
function trrm () {
if [[ "$1" == "-d" ]]; then
action="--remove-and-delete"
torrent="$2"
else
action="--remove"
torrent="$1"
fi
transmission-remote my.transmission.host --authenv -t $torrent $action
}
# clean all torrents from the queue
function trclean() {
for i in $(transmission-remote my.transmission.host --authenv -l | awk '$2=="100%" {print $1}')
do
if [[ "$1" == "-d" ]]; then
action="--remove-and-delete"
else
action="--remove"
fi
transmission-remote my.transmission.host --authenv -t $i $action
done
}
For adding torrents I use a python script so I can put them more or less automatically in folders to organize them, but that's a bit more complicated.
Some temperature conversion helpers (not used every day, but nice to have):
# temperature conversion
function c2f() {
F=$(printf "scale=2\n$1 * 1.80 + 32\n" | bc)
printf "C: $1\nF: $F\n"
}
function f2c() {
C=$(printf "scale=2\n($1 -32)/1.80\n" | bc)
printf "F: $1\nC: $C\n"
}
# for everything else, use units(1)
This one is pretty useful, as my ISP changes my public IP regularly.
# What is my External IP
function myip() { printf "External IP: %s\n" $(curl -s -4 http://ifconfig.co/) ;}
Small random ones (commented in place):
# quick and dirty file backup.
function bak() {
cp -v ${1}{,.bak}
}
# replace all spaces by underscore (only for zsh)
function mvsp() {
autoload -U zmv
zmv '* *' '$f:gs/ /_'
}
# Grep the history with 'h'
function h () {
if command -v rg > /dev/null 2>&1
then
mycommand=rg
else
mycommand=grep
fi
history 0 | $mycommand $1
}
# weather forecast on the terminal. Just fantastic.
function wf () {
CITY=$1
if [[ -z "$CITY" ]]; then
CITY="MyCity"
fi
curl wttr.in/${CITY}
}
# function to copy main ssh keys to clipboard when needed.
function pubkey () {
ssh-add -L |grep 'cardno:000000000000' |\
xclip -f -selection clipboard
echo "=> Public key copied to clipboard."
}
# Neat trick from https://github.com/lf94/peek-for-tmux/blob/master/README.md
# temporary tmux split (1/3 of the window) to look into some file
function peek() {
tmux split-window -p 33 less $@ || exit;
}
This one I use quite a bit. It's my personal pastebin:
# poor man's pastebin service (and secure !)
function pb() {
filename="$1"
dest=""
if [[ -z "$filename" ]]; then
dest=$(tr -cd '[:alnum:]' < /dev/urandom |dd bs=1 count=8 2>/dev/null)
ssh w1.e1e0.net "cat > /var/www/pastes/$dest"
else
dest=$(basename "$filename")
scp -q "$filename" "w1.e1e0.net:/var/www/pastes/$dest"
fi
echo -n "https://e1e0.net/paste/$dest" |\
xclip -f -selection clipboard
echo ''
}
It can be used like echo foo | pb
or pb myfile.txt
and will produce
a unique URL if no file name is provided.
And a shortcut and dispatcher for git
. g
executes git status -s
and
everything else is just passed to git
as is.
function g() {
if (( $# == 0 )); then
git status -s
else
git "$@"
fi
}
OpenBSD ports stuff.
And now the ports stuff. All this is probably overkill, but I use them all the time while working with ports.
As the comment at the top says this is totally stolen from other devs. I can't remember what's from who, I probably took bits and pieces from their public dot files and just adapted it to my needs.
Basically this is a dispatcher function p
. It composes the name of the
function to call. If it exists it's called, if not the _port-doas
function
is called. This is useful as I use PORTS_PRIVSEP=Yes
so everything in ports
belongs to the user _pbuild
.
Some functions make use of external commands like danj@'s show-victims
(this is actually a rewrite I did in Go, the original in Python) to look for
consumers of a port, or juanfra@'s outdated-packages.py
to query
portroach. The latter is pretty useful for "port fishing". Remember
folks, there are a lot of outdated ports without maintainer !
# ports stuff
# shamelessly stolen from Klemens Nanni (kn@), Daniel Jakots (danj@)
# and Solene Rapenne (solene@)
p() {
[ $# -gt 0 ] || return
if typeset -f \_port-"$1" > /dev/null; then
_port-"$@"
else
_port-doas "$@"
fi
}
function _port-search() {
local pt="/usr/ports"
[[ -z ${1} ]] && echo "Need a keyword to search for" && return
[[ ! -d ${pt} ]] && echo "Cannot find ports tree" && return
cd ${pt} && make search name=${1}
cd -
}
function _port-s() { \_port-search "$@" }
function _port-sql() { sqlite3 /usr/local/share/sqlports }
function _port-pldc() { make port-lib-depends-check }
function _port-ldc() { make lib-depends-check }
function _port-pdf() {
if command -v cdiff > /dev/null ; then
diff -up pkg/PLIST.orig pkg/PLIST | cdiff
else
diff -up pkg/PLIST.orig pkg/PLIST | less
fi
}
function _port-src() { cd `make show=WRKSRC` }
function _port-clean() { make clean=all }
function _port-diff()
{
if [[ -d /usr/ports/.got/ ]]; then
got diff > /usr/ports/mystuff/${PWD##*/}.diff
else
cvs diff > /usr/ports/mystuff/${PWD##*/}.diff
fi
if command -v cdiff > /dev/null ; then
cdiff /usr/ports/mystuff/${PWD##*/}.diff
else
less /usr/ports/mystuff/${PWD##*/}.diff
fi
}
function _port-df() { \_port-diff "$@" }
function _port-lessdiff() {
if command -v cdiff > /dev/null ; then
cdiff /usr/ports/mystuff/${PWD##*/}.diff
else
less /usr/ports/mystuff/${PWD##*/}.diff
fi
}
function _port-ldf() { \_port-lessdiff "$@" }
function _port-pygrep() { rg $@ --type make --glob '!*mystuff*' --glob '!lost+found' /usr/ports/*/py-* }
function _port-f() { \_port-find "$@" }
function _port-find() { rg -i $@ /usr/local/share/sqlports.list }
function _port-grep() { rg $@ --type make --glob '!*mystuff*' --glob '!lost+found' /usr/ports }
function _port-update() {
local current_dir=$(pwd)
if [[ -d /usr/ports/.got ]]; then
cd /var/git/ports.git/ && git fetch origin master:master
cd /usr/ports && got update -b master
cd "$current_dir"
else
cd /usr/ports && cvs -q up -Pd -A && cd "$current_dir"
fi
}
function _port-up() { \_port-update "$@" }
function _port-lessmake() { less "/usr/ports/$1/Makefile" }
function _port-lmk() { \_port-lessmake "$@" }
function _port-doas() {
command doas -u _pbuild "$@"
}
function _port-help() {
# (k) returns only the keys from associative array. Look zshexpn(1)
printf "%s\n" "${(k)functions[@]}" | sort | grep "^_port-" | sed 's/_port-//'
}
function _port-ou() { \_port-outdated "$@" }
function _port-outdated() {
if [ ! -x "$HOME/bin/outdated-packages.py" ]; then
echo "Cannot find script" >&2 && return
fi
"$HOME/bin/outdated-packages.py" "$@"
}
function _port-sv() { \_port-showvictims "$@" }
function _port-showvictims() {
if [ ! -x "$HOME/bin/port-showvictims" ]; then
echo "Cannot find executable" >&2 && return
fi
"$HOME/bin/port-showvictims" "$@"
}
function _port-patch {
local level=${2:-0}
patch -E -C -p$level < $1 && patch -E -p$level < $1
echo $?
}
alias py3='env FLAVOR=python3 '
function cvsdiff() {
if command -v cdiff > /dev/null ; then
cvs diff $@ | cdiff
else
cvs diff $@ | less
fi
}
And that's basically it. I hope is useful for somebody.
Have any comments ? Send an email to the comments address.