Shell Snippets

WSL pass clipboard hack

When running pass in wsl one might want to use the native windwos clip.exe program.

# ugly hack to get the clipboard in wsl to work.
pass() {
    if [[ "$1" = '-c' ]] || [[ "$1" = '--clip' ]]; then
        $(which pass) "$2" | head -n1 | clip.exe
        [[ -f ~/.pass-clr-pid ]] && kill "$(cat ~/.pass-clr-pid)"
        ((sleep 45 && echo '' | clip.exe) && rm ~/.pass-clr-pid) &
        local pid=$!
        echo "$pid" > ~/.pass-clr-pid
    else
        $(which pass) "$@"
    fi
}

WSL docker compat

Bind mount doesn't work when running the wsl client of docker with the windows server. To fix this, three things must be done:

  1. Check Expose daemon on tcp://localhost:2375 without TLS, otherwise the wsl client doesn't see it.
  2. Share the relevant drives with the containers (not specific to the present issue).
  3. Mount the drives in the wsl under /c, /d, etc. instead of /mnt/c, /mnt/d, etc.
  4. (Optional) Since it is still possible to do this: cd /mnt/d or equivalent, which will still trip up docker, we can override the cd command.

Put the following into your .bashrc to glue the wsl to windows when logging in:

export DOCKER_HOST=tcp://localhost:2375

# mount /mnt/xxx to /xxx
mount_dir() {
    mnt_path="$1"
    mnt_folder="/$(basename "$mnt_path")"
    [[ ! -d "$mnt_folder" ]] && sudo mkdir "$mnt_folder"
    if [[ "$(mount | grep '\ \/d\ ' | wc -c)" = '0' ]]; then
        sudo mount --bind "$mnt_path" "$mnt_folder"
    fi
}

# optional, autocd to /xxx instead of /mnt/xxx
cd() {
    if [[ "$1" == /mnt/* ]]; then
        builtin cd "${1:4}"
    else
        builtin cd "$1"
    fi
}

# process all folders in /mnt
for dir in /mnt/*; do
    mount_dir "$dir"
done

* To alleviate the need to type in you password at each login edit the sudoers file using visudo.

Sort music files

This script assumes, that you have a folder which has some music files dumped in the root and will move them into subfolders: music/$artist_name/$album/$title.mp3.

Example usage:

$ cd Music
$ DEBUG=1 ./sort.sh # this will show you what is going to happen
$ ./sort.sh # sort the music
#!/usr/bin/env bash

get_info_by_tag() {
    local info
    local tag
    info="$1"
    tag="$2"
    echo "$info" | sed -n 's/'"$tag"':.\(.*\)$/\1/p'
}

which eyeD3 || pip3 install eyed3
export PATH="$PATH:$HOME/.local/bin"

[[ -n "$DEBUG" ]] && debug_prefix=echo || debug_prefix=

do_work() {
    file="$1"
    info="$(eyeD3 -- "$file")"
    artist="$(get_info_by_tag "$info" 'artist')"
    album_artist="$(get_info_by_tag "$info" 'album artist')"
    title="$(get_info_by_tag "$info" 'title')"
    album="$(get_info_by_tag "$info" 'album')"

    artist_sort="$album_artist"
    if [[ -z "$artist_sort" ]]; then
        artist_sort="$artist"
    fi
    if [[ -z "$artist_sort" ]]; then
        artist_sort="Unknown"
    fi
    album_sort="$album"
    if [[ -z "$album_sort" ]]; then
        album_sort="Unknown"
    fi
    title_sort="$title"
    if [[ -z "$title_sort" ]]; then
        title_sort="$(echo "$file" | sed -n 's/.* - \(.*\)\.[a-zA-Z0-9]*/\1/p')"
    fi
    if [[ -z "$title_sort" ]]; then
        title_sort="Unknown"
    fi

    artist_sort="${artist_sort//\//_}"
    album_sort="${album_sort//\//_}"
    title_sort="${title_sort//\//_}"

    while true; do
	[[ -f "$artist_sort/$album_sort/$title_sort.mp3" ]] && title_sort="$title_sort-" || break
    done
    $debug_prefix mkdir -p -- "$artist_sort/$album_sort"
    $debug_prefix mv -v -- "$file" "$artist_sort/$album_sort/$title_sort.mp3"
}

for file in *.mp3; do
    do_work "$file"
done