r/linux4noobs Jul 01 '26

shells and scripting Share your best custom shell commands/scripts!

I want to know what custom commands/scripts you guys made that you think made a diffrence to your experience with linux or saved alot of effort for you, or even for fun, anything, i just want to hear you guys' projects and ideas

Upvotes

22 comments sorted by

u/taxigrandpa Jul 01 '26

add aliases to bashrc.

my current fav is >kapow! reboots my pc >BANG! shuts my pc down. HEHEHE

u/TheShredder9 not a noob Jul 01 '26

alias ls="ls -lah --group-directories-first --color=auto" is honestly a must-have for me.

u/Ranrhoads84 Jul 01 '26

Without a doubt the first thing I put into a bashrc

u/theminor Jul 01 '26

Same except I use l instead of ls.

u/MuaTrenBienVang Jul 02 '26

why I am getting this error
ls -lah --group-directories-first --color=auto

ls: unrecognized option `--group-directories-first'

usage: ls [-@ABCFGHILOPRSTUWabcdefghiklmnopqrstuvwxy1%,] [--color=when] [-D format] [file ...]

u/did_i_or_didnt_i Jul 01 '26

not exactly what you’re asking but I love bat (cargo)

u/gotbletu Jul 01 '26

i still use my fzf-nova everyday https://github.com/gotbletu/fzf-nova

u/BobCorndog Your situation is not unique, just use mint or fedora kde Jul 01 '26

ps -eo rss,comm | awk ‘{arr[$2]+=$1} END {for (i in arr) {print arr[i]/1024 “ MB\t” i}}’ | sort -n

you can also add -r to the end to make it do top to bottom

u/Old_County5271 Jul 01 '26

Isn't this just vmstat? You can also launch top once and grep the total

u/Old_County5271 Jul 01 '26 edited Jul 01 '26

du -bsc * | sort -n | awk 'BEGIN{split("k m g t p",OrderedStringBytes)}; function hBytes(i, x,z){x=i;while( (x/=1000) > 1){ i=x; z++ };return sprintf( "%.4g%sB", i, toupper(OrderedStringBytes[z]) )} {s=hBytes($1);$1="";print s "\t" $0} '

https://chiselapp.com/user/nmz/repository/jorp/dir?type=flat&ci=tip

u/YannisALT Jul 02 '26 edited Jul 02 '26

put the code in backup.sh. In terminal run $bash backup.sh.

This makes a copy of all my important files and settings. It backs it up to an enclosed HDD. It only backs up the files if they have changed since the last back up. It keeps the previous backup for 7 days then deletes it. I hit the power button to turn on the usb hdd. I run backup.sh. When the back up is finished (it literally takes like 10 minutes) I hit the power button on the USB HDD to turn it off. DONE! I like doing my backup manually so I can make sure shit got done. If I ever have to re-install Linux Mint, I have a Restore script that instantly copies everything back as soon as I reinstall. It puts my Desktop, my theme, my Mozilla bookmarks & accounts, I mean everything back the way it was.

#!/bin/bash

# 1. DEFINE YOUR MOUNT POINT
# run $rsync -avR --dry-run /home/user1/Desktop "$BACKUP_DIR/" if you want to check the backup worked. if it returns no files, that means it found no new files on the Source drive to backup.

START_TIME=$(date +%s)

TARGET_USB="/media/user1/Dell-SeagateBkup"
BACKUP_DIR="$TARGET_USB/backups/$(date +%F)"
LOGFILE="$TARGET_USB/backup.log"

# 2. CHECK IF THE USB IS PLUGGED IN
if [ ! -d "$TARGET_USB" ]; then
    echo "Error: USB drive not detected at $TARGET_USB"
    exit 1
fi

# 2b. CHECK IF USB IS WRITABLE
if [ ! -w "$TARGET_USB" ]; then
    echo "Error: USB is mounted read-only."
    exit 1
fi

echo "$(date): Backup started." >> "$LOGFILE"

# 3. YOUR SOURCE DIRECTORIES
SOURCE_DIRS=(
    "/home/user1/Desktop"
    "/home/user1/Documents"
    "/home/user1/Pictures"
    "/home/user1/Downloads"
    "/home/user1/.config"
    "/home/user1/.themes"
    "/home/user1/.mozilla"
    "/home/user1/.bashrc"
    "/home/user1/bin"
    "/home/user1/.local/share"
    "/home/user1/python-envs"
    "/home/user1/Projects"
)

# Create the backup directory on the USB if it doesn't exist
mkdir -p "$BACKUP_DIR"

echo "Starting backup to $BACKUP_DIR..."

# 4. LOOP THROUGH AND BACKUP EACH FOLDER
for SOURCE in "${SOURCE_DIRS[@]}"; do
    if [ -e "$SOURCE" ]; then
        echo "Backing up: $SOURCE"
        echo "$(date): Backing up $SOURCE" >> "$LOGFILE"
        rsync -avR --delete \
    --exclude="*.cache*" \
    --exclude="Cache/" \
    --exclude="cache/" \
    --exclude="*/cache/*" \
    --exclude="*/Cache/*" \
    --exclude=".cache/" \
    --exclude=".thumbnails/" \
    --exclude="Thumbs.db" \
    --exclude="lost+found/" \
    --exclude="__pycache__/" \
    --exclude="*.pyc" \
    --exclude="*.pyo" \
    --exclude=".npm/" \
    --exclude=".local/share/Trash/" \
    --exclude=".local/share/flatpak/" \
    --exclude=".config/google-chrome/Default/Cache/" \
    --exclude=".config/chromium/Default/Cache/" \
    --exclude=".mozilla/firefox/*/cache2/" \
    --exclude=".vscode/" \
    "$SOURCE" "$BACKUP_DIR/" | tee -a "$LOGFILE"
    else
        echo "Warning: $SOURCE does not exist, skipping."
        echo "$(date): WARNING - $SOURCE missing, skipped." >> "$LOGFILE"
    fi
done

# 5. PURGE OLD BACKUPS ON THE USB (Older than 7 days)
echo "Cleaning up backups older than 7 days..."
mkdir -p "$TARGET_USB/backups"

find "$TARGET_USB/backups" -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;

echo "Backup complete! Safe to unplug."
echo "$(date): Backup completed." >> "$LOGFILE"
END_TIME=$(date +%s)
ELAPSED_MINUTES=$(( (END_TIME - START_TIME) / 60 ))
echo "Backup took $ELAPSED_MINUTES minutes."
echo "$(date): Backup took $ELAPSED_MINUTES minutes." >> "$LOGFILE"

u/YannisALT Jul 02 '26

The bash script below is set to a F key binding to quickly switch the active window to my second monitor. If I hit the Function key again, it moves that same window back to the main monitor.

#!/bin/bash

WIN=$(xdotool getactivewindow)

# Get window dimensions
eval $(xdotool getwindowgeometry --shell $WIN)
WIN_W=$WIDTH
WIN_H=$HEIGHT

# Check if window is currently maximized
IS_MAXIMIZED=$(xprop -id $WIN _NET_WM_STATE 2>/dev/null | grep -c "MAXIMIZED")

# Get monitor geometries (format: WIDTHxHEIGHT+X+Y)
MONITORS=$(xrandr --query | grep ' connected' | sort -t+ -k2 -n)
MON1=$(echo "$MONITORS" | sed -n '1p')
MON2=$(echo "$MONITORS" | sed -n '2p')

# Parse monitor geometry: returns "Width Height X Y"
parse_mon() {
    local geo=$(echo "$1" | grep -oP '\d+x\d+\+\d+\+\d+')
    local w=$(echo $geo | cut -dx -f1)
    local h=$(echo $geo | cut -dx -f2 | cut -d+ -f1)
    local x=$(echo $geo | cut -d+ -f2)
    local y=$(echo $geo | cut -d+ -f3)
    echo "$w $h $x $y"
}

read M1_W M1_H M1_X M1_Y <<< $(parse_mon "$MON1")
read M2_W M2_H M2_X M2_Y <<< $(parse_mon "$MON2")

# Determine which monitor we're on, and set target
if [ "$X" -ge "$M1_X" ] && [ "$X" -lt "$((M1_X + M1_W))" ]; then
    # Currently on Monitor 1, moving to Monitor 2
    T_W=$M2_W; T_H=$M2_H; T_X=$M2_X; T_Y=$M2_Y
else
    # Currently on Monitor 2, moving to Monitor 1
    T_W=$M1_W; T_H=$M1_H; T_X=$M1_X; T_Y=$M1_Y
fi

if [ "$IS_MAXIMIZED" -gt 0 ]; then
    # Maximzed windows: move to target monitor origin (they'll fill the screen)
    xdotool windowmove $WIN $T_X $T_Y
    # Re-apply maximize (in case moving unmaximized it)
    wmctrl -ir $WIN -b add,maximized_vert,maximized_horz 2>/dev/null || true
else
    # Non-maximized windows: center on target monitor
    NEW_X=$((T_X + (T_W - WIN_W) / 2))
    NEW_Y=$((T_Y + (T_H - WIN_H) / 2))

    # Safety check: if window is bigger than monitor, just use top-left
    [ $WIN_W -gt $T_W ] && NEW_X=$T_X
    [ $WIN_H -gt $T_H ] && NEW_Y=$T_Y

    xdotool windowmove $WIN $NEW_X $NEW_Y
fi

u/YannisALT Jul 02 '26

alias spid="watch -n 2 \"sensors | awk '/Package id/ {print \$4}'\""

Install Sensors. type "spid" in terminal. When I put a new cpu on my motherboard, this is how I watched my cpu temps for the first few days. It gives you one simple package id temp and refreshes every 2 seconds.

So you put an alias in your .bashrc file. You type the alias in terminal to save time, An alias is basically a shortcut for something longer or something you type in all the time that you want to take up less characters or you can't remember the actual command. for example, I could never remember this one: 'ls -alF --color=auto' So I aliased it and now only have to type lll in terminal and hit Enter.

alias l='eza -ll --color=always --group-directories-first'

alias ll='ls -alF'

alias lll='ls -alF --color=auto'

alias la='ls -A'

alias sa="sudo apt update"

alias sau="sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y"

alias x="exit" (I just type x in terminal to close it super quick)

alias xk="xkill" (swear to god I use this one every day. It pops up a cross that you hover over any window you want immediately killed/closed because it's stuck. It's basically killing a locked-up process)

u/Astronaut6735 Jul 02 '26 edited Jul 02 '26

I wrote some scripts that use ImageMagick for basic image manipulation (flip, rotate, resize) and a script to upload an image to Imgur. They're written in Babashka, so not technically shell scripts, but they started out as bash scripts before I switched to using bb instead of bash. Resizing using find is particularly useful. E.g. resize all the png files in a directory:

find ./images -type f -name '*.png' -exec resize-img -w 1200 {} \;

That will resize every png file in the images directory to a width of 1200 px. It leaves the original files untouched, and names the new ones with -1200 in the filename.

I still need to change them slightly to allow piping (e.g. resize-img foo.jpg -w 1200 | rotate-img -d 90 | imgur).

u/sexyshingle Jul 04 '26

smack-my-bitch-up.sh

u/DavidJohnMcCann Jul 04 '26

I have a rotatable monitor which usually runs in portrait mode, landscape mode only being used for videos and spreadsheets. To switch, I use commands attached to Super-L and Super-P, like

xfce4-terminal --command="xrandr --output DisplayPort-0 --rotate normal"

Another fancy CLI trick can be demonstrated from its last use

for file in ~/astrology/*.odt; do unzip -p $file | grep -qi combustion && echo $file; done

which searches ~/astrology for an odt file containing the word "combustion".