Useful and "Use Less" Scripts

A collection of scripts I’ve created that are useful to me, while also allowing me to use less additional packages by leveraging what’s pre-installed with many Linux distros.

The scripts work on MY system and are provided AS-IS.

I made them to be modifiable and usable on any Arch-based distro, but most work out-of-the-box on non-Arch distros. Ultimately, they can be modified and used in whatever way you see fit for your system.

"Happy Scripting!"

:technologist: :writing_hand:


Scripts

Wallpaper Changer

If you are like me, you may have a folder filled with wallpapers, and you like when your wallpapers change throughout the day, in this case, every 60 seconds.

Here’s a bash script which does this using feh:

#!/bin/bash

while true; do
feh --randomize --bg-fill /path/to/wallpaper/directory &
sleep 60

done
Open Links in FreeTube (X11)

This was created based on another thread. But basically, if you copy a YouTube link, and you have FreeTube installed, this script will open the link in FreeTube.

#!/bin/bash

# Specify the application to open links
APP="/path/to/freetube"

# Create an associative array to track opened links
declare -A opened_links

# Function to open the link
open_link() {
    local link="$1"
    if [[ -z "${opened_links[$link]}" ]]; then
        opened_links[$link]=1
        $APP "$link" &
    fi
}

# Monitor the clipboard for YouTube links
monitor_clipboard() {
    local last_clipboard=""
    while true; do
        current_clipboard=$(xclip -o -selection clipboard)
        if [[ "$current_clipboard" != "$last_clipboard" ]]; then
            if [[ "$current_clipboard" =~ ^(https?://)?(www\.)?(youtube\.com|youtu\.be)/ ]]; then
                open_link "$current_clipboard"
            fi
            last_clipboard="$current_clipboard"
        fi
        sleep 1
    done
}

# Start monitoring
monitor_clipboard &
Open Links in FreeTube (Wayland)

Full instructions for Wayland can be found here:

Update Notifier (that you don't need, but I digress)

What it does:

  • Checks the Arch and AUR repos for updates using checkupdates && yay -Qua.
  • If updates are available (there will be), a notification is sent using notify-send.
  • If the user clicks it, it launches a terminal and begins the update.

Note that yay -Qua currently returns the same result as yay -Qu.
The check is done every 6 hours, but you can change it to a frequency you prefer.

Note: It uses paru instead of yay to check AUR updates because yay doesn’t seem to have a command that does this without also attempting to update.

#!/bin/bash

# Function to check for updates and send notification
check_updates() {
    updates=$(checkupdates && yay -Qua)

    if [ -n "$updates" ]; then
        notify-send -t 60000 -a "System Updates" "Updates Available" "Click to update in your terminal" -A "Update"

        if [ $? -eq 0 ]; then
            # Notification was clicked, launch alacritty and run pacman and yay
            alacritty -H -e "bash -c 'sudo pacman -Syu && yay -Sua; echo; read -p \"Press Enter to close this window...\"'"
        fi
    fi
}

# Main loop
while true; do
    check_updates
    sleep 6h
done
Periodic Reminder

Having trouble remembering to do something, like eating, taking a break, checking your to-do list? Here’s a generic reminder to help with that.

This simply uses notify-send to remind you every hour.

#!/bin/bash

# Default heading and body
HEADING="Tasks Reminder"
BODY="Check your schedule and TO-DOs."

# Check if custom heading and body are provided as arguments
if [ $# -eq 2 ]; then
    HEADING="$1"
    BODY="$2"
fi

# Function to send notification
send_notification() {
    notify-send --urgency=critical "$HEADING" "$BODY"
}

# Infinite loop to send notifications every hour
while true; do
    CURRENT_MINUTE=$(date +%M)

    # Wait until the start of the next hour
    sleep $(( (60 - CURRENT_MINUTE) * 60 ))

    send_notification
done
Weekly or Daily Reminder at a Specified Time of Day

Sometimes I find myself forgetting that I have one more thing to do before the work day is done. So, in order to ensure I do that final task, I have a specific reminder that has lots of text, so I can’t miss it, which makes it so that I am reminded to do the task. It’s a very “in your face” reminder, since I use dunst as my notification daemon — this makes the reminder appear bigger than what I’d get with a DE-specific daemon.

This simply uses notify-send to remind you at specific times, like 17:55.

#!/bin/bash

# Configuration
HEADING="Lesson Reminder"
BODY="REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER REMINDER"

# Days to run the script (1=Monday, 7=Sunday)
ACTIVE_DAYS=(1 2 3 4 5)  # Monday to Friday

# Notification times in HH:MM format
NOTIFICATION_TIMES=("16:00" "17:00" "17:30" "17:55")

# Function to send notification
send_notification() {
    notify-send --urgency=critical "$HEADING" "$BODY"
}

# Function to check if the current day is in the active days list
is_active_day() {
    local current_day=$1
    for day in "${ACTIVE_DAYS[@]}"; do
        if [ "$current_day" -eq "$day" ]; then
            return 0  # True
        fi
    done
    return 1  # False
}

# Main loop
while true; do
    CURRENT_DAY=$(date +%u)  # Get current day of the week (1=Monday, 7=Sunday)
    CURRENT_TIME=$(date +%H:%M)  # Get current time in HH:MM format

    if is_active_day "$CURRENT_DAY"; then
        for TIME in "${NOTIFICATION_TIMES[@]}"; do
            if [ "$CURRENT_TIME" == "$TIME" ]; then
                send_notification
                sleep 60  # Sleep for 60 seconds to avoid multiple notifications
                break
            fi
        done
    fi

    sleep 30  # Sleep for 30 seconds before checking again
done


Capture Video Frames from a Specific Video

Because I sometimes do animation practice, I find myself opening a video in mpv then running the capture every frame command. However, sometimes this slows down my system and I don’t ever actually want every frame. So instead, I’ve created a script that captures every fourth frame. Of course, if you find it useful, you can change how often it captures frames.

Here’s a bash script which does this using ffmpeg. In order to use it, open a terminal in the directory with the video file, then type the name of the script followed by the name of the video file like so “./cap_x_frames example_video.mp4”.

I will probably convert this to a Nemo action, because this isn’t necessarily more efficient than using the ffmpeg command directly.
But for now…

#!/bin/bash

# Set the number of frames to skip
frames_to_skip=4

# Specify the output directory here
output_dir="/path/to/output/directory"

# Check if the video file is provided
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 video_file"
    exit 1
fi

video_file="$1"

# Create output directory
mkdir -p "$output_dir"

# Get the total number of frames, frame rate, and video resolution using ffprobe
video_info=$(ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames,r_frame_rate,width,height -of csv=p=0 "$video_file")
IFS=',' read -r total_frames frame_rate width height <<< "$video_info"

# Extract the integer part of total_frames
total_frames=$(echo "$total_frames" | bc)

# Check if total_frames was found
if [ -z "$total_frames" ] || ! [[ "$total_frames" =~ ^[0-9]+$ ]]; then
    echo "Could not determine the total number of frames. Please check the video file."
    exit 1
fi

# Convert fractional frame rate to a single number
frame_rate=$(echo "$frame_rate" | bc)

echo "Total frames: $total_frames"
echo "Frame rate: $frame_rate"
echo "Video resolution: ${width}x${height}"

# Calculate the time interval between screenshots
interval=$(bc <<< "scale=6; $frames_to_skip / $frame_rate")

# Take screenshots at original resolution
ffmpeg -i "$video_file" -vf "select='not(mod(n,$frames_to_skip))'" -vsync vfr "$output_dir/frame_%d.png"

echo "Screenshots taken and saved in $output_dir"

Unison Sync Operations + Fish Alias

This script is kind of redundant, but I created it anyway. It runs Unison in a terminal and runs one-way syncs from one folder to the next based on user specified folders in the script. It is coupled with a Fish alias “uni $argv”, where “$argv” is a short name for a directory, like the ones below.

Again, this is redundant because unison can do this via commandline on its own, but I find it useful the same way I find yay or paru useful. - Yes pacman can do it, but the helpers “feel” better.

Anyway, create a Bash script, “unison.sh” and make it executable:

#!/bin/bash

# Unison one-way sync script (root1 to root2)
# This script performs one-way synchronization from a source directory (root1)
# to a destination directory (root2) using Unison.
# This is useful for backup syncs only.
# Use it in a terminal in conjunction with an alias like "uni $argv",
# where "$argv" is a short name for a directory, like the ones below.

# Function to run unison with common options for one-way sync
run_unison_oneway() { unison "$1" "$2" -batch -auto -times -perms 0 -force "$1" -ignore "Path .DS_Store" -ignore "Path Thumbs.db"; }

# Sync operations
# This case statement allows for easy addition of new sync profiles
case "$1" in
    "ff-wu")
        # Sync Firefox profile
        run_unison_oneway "/home/user/.mozilla/firefox" "/mnt/backup/firefox"
        ;;
    "docs")
        # Sync Documents folder
        run_unison_oneway "/home/user/Documents" "/mnt/backup/Documents"
        ;;
    "pics")
        # Sync Pictures folder
        run_unison_oneway "/home/user/Pictures" "/mnt/external/Photos/"
        ;;
    "code")
        # Sync code projects
        run_unison_oneway "/home/user/Projects" "/mnt/backup/Code"
        ;;
    "music")
        # Sync Music folder
        run_unison_oneway "/home/user/Music" "/mnt/nas/Music/"
        ;;
    *)
        # Display usage information if an invalid option is provided
        echo "Usage: $0 {ff-wu|docs|pics|code|music}"
        exit 1
        ;;
esac

# Inform the user that the sync operation has completed
echo "One-way sync completed for $1 (root1 to root2)"

Then, create an alias/function in Fish:

### Function to run Unison sync operations
function uni
    path/to/script/unison.sh $argv
end


Nemo Actions

Convert to MP3

Got a video file that doesn’t need to be a video anymore? Convert it to MP3.

Here’s a nemo action which does this using ffmpeg:

Create a file called something like “convert2mp3.sh”.

#!/bin/bash
for file in "$@"; do
    ffmpeg -i "$file" -vn -acodec libmp3lame -q:a 0 "${file%.*}.mp3"
done

Create another file called something like “convert2mp3.nemo_action” but make sure to place it in ~/local/share/nemo/actions.

[Nemo Action]
Name=Convert to MP3
Comment=Convert video file to MP3
Exec=/path/to/script/convert2mp3.sh %F
Icon-Name=audio-x-generic
Selection=any
Extensions=mp4;avi;webm;mkv;mov;wmv;flv;f4v;

Note: For whatever reason, the script may need to “warm up” before actually working, so you may need to run the action once to “warm it up”, and a second time to actually convert the file. It’s weird.

Convert to FLAC

Got a video file that doesn’t need to be a video anymore? Convert it to FLAC.

Here’s a nemo action which does this using ffmpeg:

Create a file called something like “convert2flac.sh”.

#!/bin/bash
for file in "$@"; do
    ffmpeg -i "$file" -vn -c:a flac -compression_level 12 "${file%.*}.flac"
done

Create another file called something like “convert2flac.nemo_action” but make sure to place it in ~/local/share/nemo/actions.

[Nemo Action]
Name=Convert to FLAC
Comment=Convert video file to FLAC
Exec=/path/to/script/convert2flac.sh %F
Icon-Name=audio-x-generic
Selection=any
Extensions=mp4;avi;webm;mkv;mov;wmv;flv;f4v;
Convert to DOCX

I’ve been using Obsidian more often, which means more Markdown files. However, the people I work with need DOCX files for review purposes. As they don’t actually want to edit the files, I don’t need to worry too much about formatting, so pandoc does what I need.

I will probably try to find a way to ensure the conversion comes out better, but this is okay for them at the moment.

Create a script called “convert2docx.sh”.

#!/bin/bash

# Check if a file is passed as an argument
if [ -z "$1" ]; then
    echo "No file provided."
    exit 1
fi

# Get the input file and output file names
input_file="$1"
output_file="${input_file%.md}.docx"

# Convert Markdown to DOCX using Pandoc
pandoc -s -o "$output_file" "$input_file"

# Notify the user of completion
notify-send "Conversion Complete" "Converted '$input_file' to '$output_file'"

Then create another file called “convert2docx.nemo_action” in ~/local/share/nemo/actions.

[Nemo Action]
Name=Convert Markdown to DOCX
Comment=Convert selected Markdown files to DOCX format
Exec=/path/to/script/convert2docx.sh %F
Icon-Name=document-save
Extensions=md;
Selection=NotNone
ImageMagick Grid/Collage From Selected Images

Use ImageMagick and Python to quickly create a grid with the selected images.
Works better with an even number of images. So, 2, 4, 6, 8, etc.

Also, the script does not resize the images, so if you want to save disk space, this script doesn’t do that. In fact, you are likely to use more space by using this script. If you have 4 images that are 1000x1000, you will end up with a new image that is 4020x4020. This is intentional.

Lastly: I’ve only tested this with jpg;jpeg;png;webp files since that’s all I had. But, it should work with other image files: bmp, tiff, raw, etc. I didn’t add these file types because they are a bit rare nowadays. You may add what you need.

Create a script: “imagemagick_grid.sh

#!/bin/bash

# Get the selected files
files=("$@")

# Get the directory of the first file
output_dir=$(dirname "${files[0]}")

# Extract the base name of the first file (without extension)
base_name=$(basename "${files[0]}" | sed 's/\.[^.]*$//')

# Set the output filename
output_file="$output_dir/${base_name}_grid.jpg"

# Check if the output file already exists
if [ -f "$output_file" ]; then
    # Append current date and time to the filename
    current_datetime=$(date +"%Y-%m-%d_%H-%M-%S")
    output_file="$output_dir/${base_name}_grid_$current_datetime.jpg"
fi

# Calculate the number of files
num_files=${#files[@]}

# Function to calculate the optimal grid dimensions
optimal_grid() {
    python3 -c "
import math
n = $1
aspect_ratio = 16/9
for cols in range(1, n+1):
    rows = math.ceil(n / cols)
    if rows / cols <= aspect_ratio:
        print(f'{cols}x{rows}')
        break
"
}

# Calculate the optimal grid dimensions
tile=$(optimal_grid $num_files)

# Use ImageMagick to create the grid
montage "${files[@]}" -background "rgba(0,0,0,0.8)" -geometry +0+0 -tile $tile "$output_file"

# Send a notification
notify-send "Image Grid Created" "Grid saved as $output_file"

Create a Nemo Action: “imagemagick_grid.nemo_action

[Nemo Action]
Active=true
Name=Create Grid with ImageMagick
Comment=Arrange selected images in a grid using ImageMagick
Exec=/path/to/script/imagemagick_grid.sh %F
Icon-Name=imagemagick
Selection=notnone
Extensions=jpg;jpeg;png;webp;jxl;
Merge Selected Images Horizontally Using ImageMagick

Create a script: “imagemagick_merge_h.sh

#!/bin/bash

# Script: merge_images_horizontal.sh
# Description: Merges selected images horizontally using ImageMagick with an 80% black background and centers the images.

# Check if ImageMagick is installed
if ! command -v convert &> /dev/null; then
    echo "ImageMagick is not installed. Please install it first."
    exit 1
fi

# Get the selected files
files=("$@")

# Check if files were selected
if [ ${#files[@]} -eq 0 ]; then
    echo "No files selected. Please select at least two image files."
    exit 1
fi

# Generate output filename
output_dir=$(dirname "${files[0]}")
base_name=$(basename "${files[0]}" | cut -f 1 -d '.')
output_file="${output_dir}/${base_name}_merged_h.jpg"

# Append date and time if file already exists
if [ -f "$output_file" ]; then
    timestamp=$(date +"%Y-%m-%d_%H-%M-%S")
    output_file="${output_dir}/${base_name}_merged_h_${timestamp}.jpg"
fi

# Merge images horizontally with an 80% black background and center align them
convert -background "rgba(0, 0, 0, 0.8)" -gravity Center "${files[@]}" +append "$output_file"

# Check if merge was successful
if [ $? -eq 0 ]; then
    notify-send "Horizontal Image Merge Complete" "Images merged successfully. Output: $output_file"
else
    echo "Failed to merge images horizontally. Please check the selected files."
fi

Create a Nemo Action: “imagemagick_merge_h.nemo_action

[Nemo Action]
Active=true
Name=Merge Images Horizontally
Comment=Merge selected images using ImageMagick
Exec=/path/to/script/imagemagick_merge_h.sh %F
Icon-Name=image-x-generic
Selection=m
Extensions=png;jpg;jpeg;gif;webp;jxl;heic;heif;
Merge Selected Images Vertically Using ImageMagick

Create a script: “imagemagick_merge_v.sh

#!/bin/bash

# Script: merge_images_vertical.sh
# Description: Merges selected images vertically using ImageMagick with an 80% black background and centers the images.

# Check if ImageMagick is installed
if ! command -v convert &> /dev/null; then
    echo "ImageMagick is not installed. Please install it first."
    exit 1
fi

# Get the selected files
files=("$@")

# Check if files were selected
if [ ${#files[@]} -eq 0 ]; then
    echo "No files selected. Please select at least two image files."
    exit 1
fi

# Generate output filename
output_dir=$(dirname "${files[0]}")
base_name=$(basename "${files[0]}" | cut -f 1 -d '.')
output_file="${output_dir}/${base_name}_merged_v.jpg"

# Append date and time if file already exists
if [ -f "$output_file" ]; then
    timestamp=$(date +"%Y-%m-%d_%H-%M-%S")
    output_file="${output_dir}/${base_name}_merged_v_${timestamp}.jpg"
fi

# Merge images vertically with an 80% black background and center align them
convert -background "rgba(0, 0, 0, 0.8)" -gravity Center "${files[@]}" -append "$output_file"

# Check if merge was successful
if [ $? -eq 0 ]; then
    notify-send "Vertical Image Merge Complete" "Images merged successfully. Output: $output_file"
else
    echo "Failed to merge images vertically. Please check the selected files."
fi

Create a Nemo Action: “imagemagick_merge_v.nemo_action

[Nemo Action]
Active=true
Name=Merge Images Vertically
Comment=Merge selected images using ImageMagick
Exec=/path/to/script/imagemagick_merge_v.sh %F
Icon-Name=image-x-generic
Selection=m
Extensions=png;jpg;jpeg;gif;webp;jxl;heic;heif;


Dolphin Service Menus

The Nemo Actions above can probably all be used in Dolphin. They just have different formatting. Check the examples below for how to create them.

ImageMagick Grid/Collage From Selected Images

Same instructions as the Nemo Action above, except you need a Dolphin Service Menu file here: “.local/share/kio/servicemenus

Create the file: “imagemagick_grid.desktop” and make it executable.

[Desktop Entry]
Type=Service
ServiceTypes=KonqPopupMenu/Plugin
MimeType=image/*; # Adjust this to include other file types if needed
Actions=createImageGrid;

X-KDE-Priority=TopLevel # Remove these two lines
X-KDE-Submenu=Image Tools # if a submenu is not wanted

[Desktop Action createImageGrid]
Name=Create Image Grid
Exec=$HOME/path/to/script/imagemagick_grid.sh %F
Icon=image-x-generic
Convert to MP3

Same instructions as the Nemo Action above, except you need a Dolphin Service Menu file here: “.local/share/kio/servicemenus

Create the file: “convert2mp3.desktop” and make it executable.

[Desktop Entry]
Type=Service
ServiceTypes=KonqPopupMenu/Plugin
Actions=convert_to_mp3
MimeType=video/*;

[Desktop Action convert_to_mp3]
Name=Convert to MP3
Exec=/path/to/script/convert2mp3.sh %F
Icon=audio-x-generic



Note: You may want to convert from one audio filetype to another, and you should be able to do so with any of the above scripts, but you will need to add those extensions to the list.

Example for Nemo Actions:

[Nemo Action]
Name=Convert to FLAC
Comment=Convert video file to FLAC
Exec=/path/to/script/convert2flac.sh %F
Icon-Name=audio-x-generic
Selection=any
Extensions=mp4;avi;webm;mkv;mov;wmv;flv;f4v;mp3;m4a;flac;wav

In this case, I’ve added 4 extra: “mp3;m4a;flac;wav

You can do the equivalent for Dolphin Service Menus.



A few other Nemo Actions I’ve already posted on the forum: [Wiki] Customising Nemo's Context Menu With Nemo Actions

May add a few more scripts, including Nemo Actions and Dolphin Service Menus later.



Terminal Shell Aliases

Some of my aliases

These all work in Fish shell. I was using one or two in Zsh before, but I no longer use Zsh, and I think the “rnsu” function only works in Fish. The only real change Zsh/Bash users would need to make is changing the double quotes " to single quotes ' iirc.

# Update Packages
## Pacman and AUR ##

alias syu="sudo pacman -Syu"
alias ss="yay -Ss"
alias rs="sudo pacman -Rs"
alias rnsu="sudo pacman -Rnsu"
alias qi="yay -Qi"
alias si="yay -Si"
alias yy="yay -Sua"
alias pu="paru -Sua"
alias yc="yay -Ycc && yay -Scd"
alias cr="checkrebuild"

## Functions

### Function to run Unison sync operations
function uni
    path/to/script/unison.sh $argv
end

### Function to send checkupdates and paru -Qua to a file then open it in micro
function cup
    set syu_date_format (date +"%Y-%m-%d_%H-%M-%S")
    set syu_log_name "/path/to/output/file/syu-$syu_date_format.sh"

    # Capture the output of checkupdates and paru -Qua
    set checkupdates_output (checkupdates | sed 's/\x1b\[[0-9;]*m//g')
    set paru_output (paru -Qua)

    # Check if there are any updates
    if test -n "$checkupdates_output" -o -n "$paru_output"
        # If there are updates, create the file and write the output
        printf "%s\n" $checkupdates_output > "$syu_log_name"
        printf "%s\n" $paru_output >> "$syu_log_name"
        sleep 0.1
        micro "$syu_log_name"
        # Remove the last two lines above if you don't need to see the output.
        # They can be replaced with syu && yy / syu && yy && fup to update immediately.
        # This is good for logging the available updates before updating.
    else
        echo "No updates found."
    end
end

### Function to remove a package and its user config files
function rnsu
    if test (count $argv) -eq 0
        echo "Usage: rnsu package_name"
        return 1
    end

    set package_name $argv[1]

    # Run the pacman command
    sudo pacman -Rnsu $package_name

    # Ask the user if they want to remove the related files
    read -P "Would you like to remove the related configs for \"$package_name\"? (y/n): " response

    if test "$response" = "y"
        set directories ~/.config ~/.cache ~/.local/share
        set found_items 0

        for dir in $directories
            set -l matches (find $dir -maxdepth 2 -iname "*$package_name*")
            if test (count $matches) -gt 0
                set found_items 1
                for match in $matches
                    echo "Found: $match"
                end
            end
        end

        if test $found_items -eq 1
            read -P "Do you want to move these items to the trash? (y/n): " confirm
            if test "$confirm" = "y"
                for dir in $directories
                    set -l matches (find $dir -maxdepth 2 -iname "*$package_name*")
                    for match in $matches
                        echo "Moving to trash: $match"
                        trash -v $match
                    end
                end
                echo "Related files and folders for \"$package_name\" have been moved to the trash."
            else
                echo "No items have been moved to the trash."
            end
        else
            echo "No related files or folders found for \"$package_name\"."
        end
    else
        echo "No files or directories have been removed or sent to the trash."
    end
end

## Flatpak, AppImage, etc. ##
alias fup="flatpak update"

## Git ##

alias gp="git pull"
alias gf="cd Appz/GIT_PKGS/"
alias gl="git log -p"
alias gitparu="cd Appz/GIT_PKGS/paru-git/; git pull; cd"
alias gitparup="cd Appz/GIT_PKGS/paru-git/; makepkg -si; cd"
alias gitqimgv="cd Appz/GIT_PKGS/qimgv/; git pull; cd"
alias gitqimgvup="cd Appz/GIT_PKGS/qimgv/build/; sudo make install; cd"
alias gitfsearch="cd Appz/GIT_PKGS/fsearch/; git pull; cd"
alias gitfsearchup="cd Appz/GIT_PKGS/fsearch/; meson builddir; ninja -C builddir install; cd"
alias gpa="cd Appz/GIT_PKGS/paru-git/; git pull; cd; cd Appz/GIT_PKGS/qimgv/; git pull; cd; cd Appz/GIT_PKGS/fsearch/; git pull; cd"


To see any previous versions for scripts, click the edit history button.

PS: I’m open to suggestions about efficiency, and questions in general about scripts.

10 Likes

It’s wonderful when a few lines of script can replace an app for a task. I use a wallpaper changer written in python:
import os
import random
import subprocess
import time

picture_dir = “path_to_wallpaper”

while True:
# Get a list of all the picture files in the directory
picture_files = [f for f in os.listdir(picture_dir) if f.endswith(“.jpg”) or f.endswith(“.png”)]

# Choose a random picture from the list
random_picture = os.path.join(picture_dir, random.choice(picture_files))

# Set the desktop background using the feh command
subprocess.run(["feh", "--bg-fill", random_picture])

# Wait for 11 minutes before changing the background again
time.sleep(660)

that also uses feh. I use it in Openbox. I call it by adding

python3 ~/.local/bin/change-background.py &

to ~/.config/openbox/autostart because I want the action confined to openbox and to execute automatically on login to an openbox session.
I am totally satisfied, but I’d like to know, ddnn, how I could call your wallpaper script in a similar way to execute automatically on login and similarly confine it to openbox or another WM.
Thanks for these!

4 Likes

You’re welcome.


Include this in your autostart:

bash /path/to/wallpaperScript/auto-wp.sh &

I actually call mine using a shortcut, because I share my screen for most of the day.
So, I use one shortcut for work-friendly wallpapers (just two images in this case), and another for my favourites.

The shortcuts look like this (using sxhkd):

super + shift + r
    pkill -f 'auto-wp'|feh --randomize --bg-fill /path/to/wp/directory

super + alt + r
    /path/to/wallpaperScript/auto-wp.sh

One script kills the wallpaper changer then sets a random work-friendly wallpaper, and the other starts the wallpaper changer.

1 Like

What bitrate is this?

I don’t remember if I considered bitrate when making the script.

However, I just converted a video that showed a variable bitrate from 86-107 kbps. As an audio file, it shows 233-246 kbps.

Not sure if that’s a good thing or bad thing, but there is no drop in audio quality, nor improvement. (Just found out higher bitrate is a good thing)

Actually, I do remember having issues with volume when creating it, but I worked that out, so now the volume is the same.

Update: The -q:a 0 section outputs the audio at the highest quality.

  • -q:a: This option sets the quality of the audio encoding. The “a” denotes that this is an audio quality setting.
  • 0: This value specifies the highest quality for MP3 encoding. The range typically goes from 0 (highest quality) to 9 (lowest quality).

I haven’t done mp3 in several years since I switch everything to flac this was the command I was using and it allowed you to tell it the bitrate you want I choose. Heres the command if you want to play with it.

for filename in *; do
  original=$filename
  #/ audio name uses cut and rev to remove extention mp4 for ext mp3
  audioname=`echo $original | rev | cut -c 5- | rev`
  echo -e "Now Extracting ${audioname}"
  ffmpeg -i "$original" -vn -ar 44100 -ac 2 -ab 320k -f mp3 "${audioname}.mp3"  > /dev/null 2>&1

here is the information of a converted file
codec

I don’t know if there is any difference in the two commands as far as sound quality as I just woke up and havent gotten there.

I can’t hear a difference from my end.

1 Like

I’m surprised this script spat out a 192kb/s bitrate file - to me it looks like it’s set up for a CBR at 320kb/s, and I don’t see any switches that would have enabled VBR instead which might have identified itself in the metadata as an average of 192kb/s.

Maybe I’m just rusty on my ffmpeg :smile:

that could be just the wrong picture as I don’t use that anymore. I had just woke up when i posted.

2 Likes

That makes sense, I know the feeling!

2 Likes

In my test, it was a CBR of 320 kbps. So yeah:


1 Like

RE: if this inflated file size is a good thing or a bad thing - it could go either way! It will mostly depend on what format the original audio is in - we’ve come a long way since MP3 was the king of the hill, and modern codecs often produce the same quality of audio at lower bitrates, so you will occasionally find yourself with MP3 encoded tracks that come out bigger than other codecs despite sounding identical.

Theoretically it could a ‘bad thing’ if encoding with CBR - while MP3 encoding is akin to black magic, it can’t create extra quality from a lossy file out of thin air so the inflated filesize from increasing the bitrate won’t be doing anything :laughing:

However, it’s only bad on paper - with modern storage capacities, it’s not worth worrying about the occasional oversized MP3.

For reference, 320kb/s is the maximum bitrate MP3 encodes in - in a similar vein, using the -q:a 0 switch as you are here is giving a theoretical best quality while assuming for VBR in order to balance quality against the total file size.

Ultimately if you’re satisfied with it then that’s all that matters, but in technical terms 320kb/s CBR is the ‘best’ quality of audio for encoding an MP3.

2 Likes

In my case, I created this script for two reasons:

  1. TED Talks videos and others that don’t need to be in video form
  2. Music uploaded to YouTube that say “Official Audio”

So, in my case, quality is mostly an afterthought.

1 Like

Thank you for sharing! Will be running the FreeTube links and DOCX conversions on my system :smiley:

2 Likes

just for you knowledge

instead of downloading videos and then converting them you can just us yt-dlp to do the conversion for you

yt-dlp -x --audio-format mp3 $URL -o/place/to/store

2 Likes

I use JDownloader2, so I usually download the audio files through that. It also allows me to download thumbnails, captions, etc.

However, sometimes the “Official Audio” songs, or the TED Talks videos, etc. have actual video to watch (like visualisers and unorthodox talks), and then I decide I want to keep it, but not in video form. So this little script allows me to just convert it without finding the YT link again and selecting the audio.



PS: I actually rarely use this script because most times I download both the audio and video from the start if I think I may want the audio. But, it’s useful when needed.

1 Like

I have kept my script for the conversion for those times I may want the audio for a trip. however i find most of the time i can just play the video its not like i have to look at it however i haven’t needed it for my phone in years which is why i originally thought i would need to keep it.

Yeah, I could just listen to videos without watching them, but I guess it’s also good for saving space. Not that I need to since I have 2 TBs free.

1 Like

Updated the Weekly Reminder script so that the days are more easily modifiable.

# Days to run the script (1=Monday, 7=Sunday)
ACTIVE_DAYS=(1 2 3 4 5)  # Monday to Friday

# Function to check if the current day is in the active days list
is_active_day() {
    local current_day=$1
    for day in "${ACTIVE_DAYS[@]}"; do
        if [ "$current_day" -eq "$day" ]; then
            return 0  # True
        fi
    done
    return 1  # False
}

Added “Convert to FLAC” Nemo Action. I may make a submenu.
Added “ImageMagick Grid/Collage From Selected Images” Nemo Action.
Added “ImageMagick Grid/Collage From Selected Images” Dolphin instructions.
Added “Convert to MP3” Dolphin instructions.
Added “Merge Selected Images Horizontally/Vertically Using ImageMagick”

1 Like

Not scripts, but aliases. Because sometimes a task is so simple an alias will do the job…

First up, you know when you realise you needed to sudo your last command? Personally, I just wish I could tell the terminal to just dewit. Now I can:

alias dewit='sudo $(fc -ln -1)'

I actually don’t use ffmpeg or the default builds of flac to convert anything to FLAC format, I use a build of flac that uses multithreading which goes very fast. Like, stupid fast. Fast as balls. But you do need to remember to tell it to use a bunch of threads and the high compression level, so I just wrote an alias so I don’t have to:

alias flac='flac -j12 -8p'

Not sure if any of this is good practice or not, but it’s very entertaining (if I’m being stupid, don’t hesitate to tell me, I’m always eager to learn). They’re both in my ~/.bashrc

2 Likes