Bash

Table of Contents

1. Shell movements

 Shell movements
 ===============

Cursor position represented by []
---------------------------------

 ctrl-a <-----------------> ctrl-e  | moving
  alt-b    <-------->        alt-f  |
 ctrl-b       <-->          ctrl-f  |

      $ mv file[].txt dir/

 ctrl-w    <-------->       alt-d   | erasing
 ctrl-u <-----------------> ctrl-k  |

2. Interactive Shells

3. Bash Startup Files

3.1. Prevent autostart for programs when inside an Emacs shell

To avoid running programs that may not render well within an Emacs shell when loading ~/.bashrc etc

if [[ -z $INSIDE_EMACS ]]
then
    # Things to do when not using a shell inside Emacs
fi

4. Figuring out the amount of / in a string

path="/home/user/dir1/dir2"
num="$(( "$(echo "${path%/}" | tr -cd '/' | wc -c)" + 2 ))"

5. Function to ensure only 1 argument and its a file named foo.json

usage() {
    if [[ $# -eq 1 && ${1##*/} == 'foo.json' && -f $1 ]]
    then
        file="$1"
        return 0
    else
        printf '\n  [\e[1;31mx\e[0m] File not found\n'
        printf '\n  [\e[1;32mi\e[0m] Usage: ./%s file.json\n\n' "${BASH_SOURCE[0]##*/}"
        return 1
    fi
}

6. Parameter expansion

6.1. Return the same value from 2 different strings

Return everything after the last = or / from any of these 2 variables

youtube_link_channel="https://yewtu.be/feed/channel/foo"
# OR
youtube_link_channel="https://www.youtube.com/feeds/videos.xml?channel_id=foo"

youtube_channel_id="${youtube_link_channel##*[=/]}" # = "foo"

7. Unset values in array

# Iterate over the green blocklists
for green_blocklist in "${green_blocklists[@]}"
do
    # Remove green blocklists from the blue blocklists array
    for index in "${!blue_blocklists[@]}"
    do
        if [[ ${blue_blocklists[index]} == "$green_blocklist" ]]
        then
            unset 'blue_blocklists[index]'
            blue_blocklists=("${blue_blocklists[@]}")
        fi
    done
done

8. Print the commands as they are executed

set -x

9. Oneliner to find dotfiles packages not managed by Ansible

sort -u ~/.dotfiles/.pkg* | while read -r pkg; do grep -qr "$pkg" ~/repos/ansible-dotfiles || echo "pkg not found: $pkg"; done

10. Display all locations containing an executable

type -a foo

11. Print commands and their arguments as they are executed

++ in the output mean forking/subshell

bash -x script.sh

12. Check for unset variables

bash -u <file>

13. Pipe status exit codes

false | true | false | false
echo "${PIPESTATUS[*]}"

14. Date using strftime(3)

Print the date using builtin printf and strftime(3).

local date
printf -v date '%(%Y-%m-%d)T'
echo -n "$date"

15. Array of files basename

fn() {
    local files=(/path/to/files/file*)
    files=("${files[@]##*/}")

    declare -p files
}

16. Reminder for ## and %% parameter expansion

Comments start with #..

17. References