Skip to content

Instantly share code, notes, and snippets.

@thrau
Last active August 28, 2020 12:37
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thrau/6aabee2dc05456a2812e14ca49da1ceb to your computer and use it in GitHub Desktop.
Save thrau/6aabee2dc05456a2812e14ca49da1ceb to your computer and use it in GitHub Desktop.
Why I write shell scripts

I write scripts to:

  • combine a sequence of commands i could type manually, but am too lazy to (example: proxy-chrome)
  • turn commands i need frequently but can't remember into ones i can (example: ex, ssh-forward, ishostup, rmcaps)
  • do things recursively on a file tree (rgit, mvnrc, chres)
  • perform transformation operations on many files that are too complicated for find (svg2pdf, imgscale)
  • systematize workflows into a script (mvn-release)
  • procrastinate (gdwc)

The given examples are a subset of all the scripts I have in my doftiles that can be found in thrau/dotfiles.

proxy-chrome() {
    port=$(python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()')

    ssh -D ${port} -q -C -N "$@" &
    PROXY_PID=$!

    chromium-browser \
        --proxy-server="socks5://localhost:${port}" \
        --host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE localhost"

    kill $PROXY_PID
}

# extract any file
ex () {
    if [ -f $1 ] ; then
        case $1 in
            *.tar.bz2)   tar xvjf $1    ;;
            *.tar.gz)    tar xvzf $1    ;;
            *.tar.xz)    tar xvJf $1    ;;
            *.bz2)       bunzip2 $1     ;;
            *.rar)       unrar x $1     ;;
            *.gz)        gunzip $1      ;;
            *.tar)       tar xvf $1     ;;
            *.tbz2)      tar xvjf $1    ;;
            *.tgz)       tar xvzf $1    ;;
            *.zip)       unzip $1       ;;
            *.Z)         uncompress $1  ;;
            *.7z)        7z x $1        ;;
            *.exe)       cabextract $1  ;;
            *.jar)       jar xvf $1     ;;
            *.xz)        unxz $1        ;;
            *)           echo "'$1': unrecognized file compression" ;;
        esac
    else
        echo "'$1' is not a valid file"
    fi
}

ssh-forward() {
    # wrapper around ssh -N
    # ssh-forward user@remote.com 8080 7700:5000 ...

    export host=$1
    shift
    # export ports="$@"

    portargs() {
        for port in "$@"; do

            if [[ $port =~ ^[0-9]{2,5}$ ]]; then
                echo "\-L ${port}\:localhost\:${port}"
            elif [[ $port =~ ^[0-9]{2,5}:[0-9]{2,5}$ ]]; then
                port_local=$(echo $port | cut -d':' -f 1)
                port_remote=$(echo $port | cut -d':' -f 2)
                echo "\-L ${port_local}\:localhost\:${port_remote}"
            else
                echo "Bad forwarding specification '$port'" 1>&2
            fi

        done
    }

    ssh -N $(portargs "$@" | xargs) $host
}

# use nmap to check whether a host is up
ishostup() {
    nmap -sP --host-timeout=250ms $1 | grep "Host is up" > /dev/null

    if [ $? -eq 0 ]; then
        echo "yes"
        return 0
    else
        echo "no"
        return 1
    fi
}

# remap control to caps lock (remove capslock)
rmcaps() {
    xmodmap -e 'remove Lock = Caps_Lock'
    xmodmap -e 'keysym Caps_Lock = Control_L'
    xmodmap -e 'add Control = Control_L'
}


## recursive git
rgit() {
    for f in $(find -L -name .git -a -type d | sed "s/^\.\///"); do
        d=$(dirname $f)
        echo -e "\e[1;34m${d}\e[0m"
        (cd $d; git "$@")
        echo
    done
}

## maven recursive clean (this is so ugly ...)
mvnrc() {
    # remove all abandoned bundles first
    for target in $(find -type d -name "target"); do
        dir=$(dirname $target)
        pom=$dir/pom.xml

        if [ -f $pom ]; then
            echo -n "cleaning $dir ..."
            (cd $dir; mvn -fn -B -q clean)
            echo " done!"
        fi
    done
}

# chmod restore
#   recursively sets chmod of files to 644 and directories to 755
chres() {
    if [ $1 ]; then
        folder=$1
    else
        folder="."
    fi

    find $folder -type d -exec chmod 755 "{}" \;
    find $folder -type f -exec chmod 644 "{}" \;
}

## convert svgs to pdfs
svg2pdf() {
    IFS=$'\n'

    for f in $*; do
        bname=$(basename $f)
        name=${bname%.*}

        svg=$(dirname $f)/$name.svg
        pdf=$(dirname $f)/$name.pdf

        if [ $svg -ot $pdf ]; then
            echo "skipping $svg"
            continue
        fi

        echo "converting $svg -> $pdf"
        inkscape -D -z --file="$svg" --export-pdf="$pdf"
    done
}

imgscale() {
    factor=$1
    shift

    for img in "$@"; do
        width=$(identify -format "%w" "${img}")
        nwdith=$(( $factor * $width ))
        nwdith=$(printf "%.0f" "${nwdith}")

        ext=${img##*.}
        fname=$(basename $img ".$ext")
        nfname="${fname}_scaled.${ext}"

        convert ${img} -resize ${nwdith} -quality 95 ${nfname}
    done
}

mvn-release() {
    if [ $1 ]; then
        release=$1
    else
        release="minor"
    fi

    echo "Determining release version..."

    MVN_VERSION=$(mvn -q \
        -Dexec.executable="echo" \
        -Dexec.args='${project.version}' \
        --non-recursive \
        org.codehaus.mojo:exec-maven-plugin:1.3.1:exec)

    MVN_VERSION="${MVN_VERSION/-SNAPSHOT/}"

    echo "... is $MVN_VERSION"

    vers=(${MVN_VERSION//\./ })

    v_major=${vers[0]}
    v_minor=${vers[1]}
    v_patch=${vers[2]}

    next_major=$(($v_major+1))
    next_minor=$(($v_minor+1))
    next_path=$(($v_patch+1))


    releaseVersion=$MVN_VERSION
    tag="v$releaseVersion"

    case $release in
        "major")
        developmentVersion="$next_major.0.0-SNAPSHOT"
        ;;
        "minor")
        developmentVersion="$v_major.$next_minor.0-SNAPSHOT"
        ;;
        "patch")
        developmentVersion="$v_major.$v_minor.$next_patch-SNAPSHOT"
        ;;
        *)
        echo "[ERROR]: unknown release type '$release'"
        exit 1
        ;;
    esac

    echo "Next development version is $developmentVersion"

    cmd="mvn release:prepare -Psonatype-oss-release -DautoVersionSubmodules=true -DreleaseVersion=$releaseVersion -DdevelopmentVersion=$developmentVersion -Dtag=$tag -DpushChanges=false"
    echo "$cmd"
    echo "Execute this? [y/n]"
    read answer

    case $answer in
        "y") ;;
        *)
        echo "Okay, bailing"
        exit 1
    esac

    $cmd
}

# "git diff word count" counts the words that were added or removed in a diff
# useful for checking how much thesis writing you got done
gdwc() {
    a=$(git diff "$@" | grep "^+" | wc -w)
    d=$(git diff "$@" | grep "^-" | wc -w)

    echo $(($a - $d))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment