Dash (Debian Almquist shell)

Dash (Debian Almquist shell) is a modern POSIX-compliant implementation of /bin/sh (sh, Bourne shell).

Dash is not Bash compatible, but Bash tries to be mostly compatible with POSIX, and thus Dash.

Dash is roughly 4 times faster than Bash in speed and very limited resources like space, RAM or CPU. As minimalistic as possible, much smaller than Bash comparing 134.1 KB vs 6.5 MB installed. Dash is a long-established, tiny project with simple and long-established functionality; one that is still very alive and with many active developers. Thus, Dash has a much smaller attack surface, while still having many eyes on its code.

The following example dash script is to manage your plain text notes in a folder using neovim. It is a very straight and fucking fast single script.

#!/bin/dash

# check if it is run as ROOT and exit.
ROOID=$(id -u)
if [ $((ROOID)) -eq 0 ]; then
    notify-send "clean exit" "Oop! it was run as ROOT. please run it as NORMAL user again."
    exit 0
fi

# check if it is running in terminal. otherwise exit.
case "$(ps -o stat= -p $$)" in
    *+*) clear; echo "\ndamshote continue..." ;;
    *) notify-send -t 2700 "clean exit" "please run it in terminal." ;;
esac

# check it is already running and exit.
SCRIPTNAME="$(dirname -- "$0")"
if pidof -x "$SCRIPTNAME" > /dev/null 2>&1; then
    echo "Oop! it is already running. clean exit"
    exit 0
fi

HEREDIR="$(dirname "$(readlink -f "$0")")"
NOTEDIR=""$HEREDIR"/damshote-notes-dir"
TRASHDIR=""$HEREDIR"/damshote-trash-dir"
mkdir -p "$NOTEDIR"
mkdir -p "$TRASHDIR"
GENFILE=""$HEREDIR"/contentcpmvfodesgen"

# generate list of files and folders in the current directory
# content generate
contentgen_func () {
    if [ -f "$GENFILE" ]; then
        rm "$GENFILE"
    fi
    if [ "$PWD" = "$NOTEDIR" ]; then
        local FIFORAW=$(echo "EXIT\nNew-FILE\nNew-FOLDER" && ls --group-directories-first --file-type .)
    else
        local FIFORAW=$(echo "EXIT\nNew-FILE\nNew-FOLDER" && ls -a --group-directories-first --file-type . | grep -v "^\.[0-9a-zA-Z]\|^\./$")
    fi
    local NUM=0
    for FIFO in $FIFORAW; do
        local ZLNUM=$(printf "%03d" "$NUM")
        echo ""$ZLNUM". "$FIFO" @ "$ZLNUM""
        local NUM=$((NUM+1))
    done > "$GENFILE"
    echo; cat "$GENFILE"; echo
}

# cp mv folder destination generate
cpmvfodesgen_func () {
    if [ -f "$GENFILE" ]; then
        rm "$GENFILE"
    fi
    local FOLIST=$(echo "EXIT\n../" && ls -d */ 2>/dev/null)
    local NUM=0
    for FOLDER in $FOLIST; do
        local ZLNUM=$(printf "%03d" "$NUM")
        echo ""$ZLNUM". "$FOLDER" @ "$ZLNUM""
        local NUM=$((NUM+1))
    done > "$GENFILE"
    echo; cat "$GENFILE"; echo
}

# selecting by number
selection_func () {
    while true; do
        read -p "Select Number: " SELNUN
        # correct selected number
        unset CORRECNUM
        case "$SELNUN" in
            [0-9]|[0-9][0-9]) CORRECNUM=$(printf "%03d" "$SELNUN") ;;
            [0-9][0-9][0-9]) CORRECNUM="$SELNUN" ;;
            e|exit|q|quit) exit 0 ;;
            *) echo "Oop! invalid selection. try again."; continue ;;
        esac
        SELECTED=$(cat "$GENFILE" | grep "^$CORRECNUM" | cut -d ' ' -f 2)
        if [ -z "$SELECTED" ]; then
            echo "Oop! selection is empty. try again."; continue
        fi
        break
    done
}

# copy and move function
copymove_func () {
    SELFILE=$(readlink -f "$SELECTED")
    unset SELECTED
    cpmvfodesgen_func
    selection_func
    SELDEST=$(readlink -f "$SELECTED")
    if [ "$1" = "copy" ]; then
        cp "$SELFILE" "$SELDEST"/
    fi
    if [ "$1" = "move" ]; then
        mv "$SELFILE" "$SELDEST"/
    fi
}
# open and go to directory
opengoto_func () {
    if [ -d "$SELECTED" ]; then
        cd "$SELECTED"
    fi
    if [ -f "$SELECTED" ]; then
        nvim "$SELECTED"
    fi
}
# rename file or folder
renamefifo_func () {
    read -p "Type New Name: " NEWNAME
    mv "$SELECTED" "$NEWNAME"
}
# delete file or folder
deletefifo_func () {
    local SELFIFO=$(readlink -f "$SELECTED")
    if [ -f "$SELFIFO" ] || [ -d "$SELFIFO" ]; then
        mv "$SELFIFO" "$TRASHDIR"/
    fi
}

# step one operations
steponeopera_func () {
    unset STEPTWO
    if [ "$SELECTED" = "EXIT" ]; then
        exit 0
    fi
    if [ "$SELECTED" = "New-FILE" ]; then
        read -p "Type New-FILE name without space: " FILENAME
        nvim "$(date +'%Y%m%d-%H%M%S')___"$FILENAME""
        STEPTWO=0
        return
    fi
    if [ "$SELECTED" = "New-FOLDER" ]; then
        read -p "Type New-FOLDER name without space: " FOLDERNAME
        mkdir "$(date +'%Y%m%d-%H%M%S')___"$FOLDERNAME""
        STEPTWO=0
        return
    fi
    if [ "$SELECTED" = "BACK" ]; then
        cd ../
        STEPTWO=0
        return
    fi
    STEPTWO=1
}

# step two operations
steptwoopera_func () {
    if [ $((STEPTWO)) -eq 0 ]; then
        return
    fi
    echo "
    o -> Open/GoTo
    c -> Copy
    m -> Move
    r -> Rename
    d -> Delete
    b -> Go-BACK
    q -> EXIT/QUIT
    e -> EXIT/QUIT
    "
    read -p "Type Character: " SELCHAR
    case "$SELCHAR" in
        o)
            opengoto_func
            ;;
        c)
            copymove_func copy
            ;;
        m)
            copymove_func move
            ;;
        r)
            renamefifo_func
            ;;
        d)
            deletefifo_func
            ;;
        b)
            echo "\ndamshote continue..."
            ;;
        q)
            exit 0
            ;;
        e)
            exit 0
            ;;
        *)
            opengoto_func
            ;;
    esac
}

# start main
cd "$NOTEDIR"
while true; do
    contentgen_func
    selection_func
    steponeopera_func
    steptwoopera_func
    clear
    echo "\ndamshote continue..."
done

Comments

Popular posts from this blog

printf - Printing with format

rebase or no-rebase for git pull

dmmsh-wlr for managing outputs in Wayland using wlr-randr