Skip to content

Shells

fish

Fish switch statements look completely different from bash case statements, with an incompatible syntax.

Conditionally setting $PATH:
switch "$PATH" # (1)
    case "*$HOME/.cargo/bin*" # (2)
        echo '$PATH already contains $HOME/.cargo/bin' # (3)
    case '*'
        set --global PATH $HOME/.cargo/bin $PATH # (4)
end # (5)
  1. Because the $PATH is rendered as a list delimited by whitespace, without quotes this statement will be expanded to many arguments and will produce an error.
  2. Double quotes must be used, because with single quotes fish will not expand the $HOME variable.
  3. I have not found an empty placeholder similar to pass in Python which could simply occupy space here. Without a statement, fish appears to execute the following block by default.
  4. Environment variables use the set keyword. The --universal option, which would otherwise make sense here, does not work because $PATH is a global variable. Note that there is no equal sign, only a space separating the variable identifier and value.
  5. Bash equivalent
    case ":${PATH}:" in
        *:"$HOME/.cargo/bin":*)
            ;;
        *)
            export PATH="$HOME/.cargo/bin:$PATH"
            ;;
    esac
    
Setting environment variables
set -x EDITOR /usr/bin/vim # (1)
  1. Without -x this variable will not be visible to applications.
    Bash equivalent
    export EDITOR=/usr/bin/vim
    

Fish for-in loops are concluded with end.

Set metadata in a loop
for i in $(exa Godfrey*)
    echo Processing $i
    set title $(string replace -r "\(.*mp3$" "" $i) # (1)
    ffmpeg -i $i -metadata title="$title" -metadata album="Godfrey" -metadata artist="Vlad TV" -codec copy output/$i
end

  1. string replace is used here to remove the ending of a filename, including extension.

bash

The systemwide config for bash is at /etc/profile.

Command-line arguments are available as the positional arguments $1, $2, etc. with the script itself being $0. Handling command-line arguments is conventionally done with the shift command in a while loop.

Conditionally setting $PATH
case ":${PATH}:" in
    *:"$HOME/.cargo/bin":*)
        ;;
    *)
        export PATH="$HOME/.cargo/bin:$PATH"
        ;;
esac

The shopt internal command is used to set (-s) or unset (-u) various shell settings.

Disable case sensitivity
shopt -s nocasematch
Tag audio with metadata
#!/bin/bash
tag () {
    TAG=$1 ; shift # First arg has to be a valid tag name.
    shopt -s nocasematch
    case $TAG in
        "amapiano")
            while [ $# -gt 0 ]
            do
               INPUTFILE="$1"
               ffmpeg -i "$INPUTFILE" -metadata genre=Amapiano -c copy "${INPUTFILE/./_tagged.}"
               shift
            done
            ;;
        *)
            echo "Invalid tag!"
            ;;
    esac
    shopt -u nocasematch
}

A more useful and less brittle version of this script may be possible using the getopts function to define a named parameter, rather than forcing the first positional argument to be one of a number of set values.