Shell tips for day-to-day work

Which shell do you use for work each day? Do you have any tips to improve efficiency? Any functions you wrote that make certain tasks faster?

I recently switched to fish and have been thoroughly enjoying it. It offers command completion suggestions based on your history, which is really useful because I sometimes find myself running the same commands frequently. It is also able to tab-complete the options and flags associated with many commands (if I remember correctly, it scans the man pages for those, which is really cool). It is also fairly easy to write a completion script for an existing command, and I was able to get it working really well for one of our internal tools.

One shell trick that I used in bash quite often was running sudo !!. The !! in bash expands to the previously run command, so this let’s you easily re-run the previous command as root. fish doesn’t have this, but it does prepend sudo if you press alt+s, which is still helpful.

Here’s one fish function that I wrote which helps me quickly run updates on all my packages:

function pkgup
  sudo apt update && sudo apt full-upgrade
  brew update && brew upgrade
  sudo snap refresh
  kubectl krew update && kubectl krew upgrade

Here’s another that lets me easily switch my Kubernetes context:

function kcon
  switch $argv[1]
  case [k8s context 1]
    kubie ctx [k8s context 1 name]
  case [k8s context 2]
    kubie ctx [k8s context 2 name]
  case [etc.]
  case '*'
    echo (set_color brred) "Invalid context: $argv[1]"
    echo (set_color normal) "Contexts: [list of k8s contexts]"

I wrote it as a switch statement like that so that I can refer to my Kubernetes contexts by a different name than their real one. I find this useful because any kubeconfig created by k3d has the prefix k3d- which isn’t fun to type each time.

1 Like

I still use bash, as it generally makes it easier to share things I’ve made for myself with coworkers and customers.

I’ve organized basically all of my bashrc functions and aliases under files in ~/.config/bashrc.d. They get prepended with a number and are then sourced in order by something like this in ~/.bashrc:

for SRCFILE in $(ls ~/.config/bashrc.d); do
    source $SRCFILE

I do essentially the same for ~/.profile. This makes it much easier to organize without having a giant bashrc file, and also allows you to check these extensions into your dotfiles and just source them from wherever you store them.

A little function I’ve grown quite fond of recently:

up() { cd $(eval printf '../'%.0s {1..$1}) && pwd; }

This one can be handy to quickly open files with their default app, if you always forget the name for xdg-open like I do:

alias run="xdg-open"

List and search your git log commits:

function gl() {
    git log \
        --color=always \
        --date='format:%a, %b %d' \
        --pretty='format:%C(red)%h %C(blue)<%ad> %C(reset)%s' \
    | fzf \
        --preview='git log --color=always -n1 $(echo {} | cut -f1 -d" ")' \
        --preview-window=up:70% \
        --ansi \
        --multi \
    | xargs \
        -L1 \
        -I'{}' \
        bash -c 'git log --format=%H -n1 $(echo '"'{}'"' | cut -f1 -d" ")'