Handy scripts you'd like to share

I moved that to my own server: UltraBlack/srbs: Simple Rsync backup service - srbs - Wanna have a cup of GitTea?

Forgot to edit the post (Can't do that anymore too apparently)

1 Like

My Wallpaper change script for i3. Changes my background every 5 minutes to a random wallpaper.

Had a simpler script but it kept running when you logged out, resulting in multiple scripts running on login again (I seldom logout except if I'm restarting/shutting down, but if your testing your i3 startup, you have to). So it checks if i3 is running and exits if not.

#!/bin/bash

changeWallpaper() {
	#PIC=($(find ~/Pictures/Wallpaper/widescreen -type f | shuf -n 1 --random-source=/dev/random))
	feh --randomize --bg-fill ~/Pictures/Wallpaper/widescreen
}

changeWallpaper
COUNT=0
while true
do
	#check to see i3 is running.  The socket should come back.
    COUNT=$((COUNT+1))
	SKT=`exec i3 --get-socketpath`
	if [ -z "$SKT" ]
	then
		exit 0
	fi;
	#else
	if [ $COUNT -eq 120 ]
	then
		#change wallpaper and reset
		COUNT=0
		changeWallpaper
	fi;
	sleep 5s

done

The commented line in changeWallpaper was for my brother who had two monitors, and needed two different pictures, Set "shuf -n 2" and you'll get an array of two different filenames.

2 Likes

A script to perform an action on all BTRFS subvolumes. Change lines including arch-chroot as you wish. In my case I am mass uninstalling 4 packages.

#!/bin/bash
for i in `sudo ls -d /.snapshots/*/snapshot` ;
do 
	sudo btrfs property set $i ro false
	sudo mount --bind $i $i
	sudo arch-chroot $i rm /var/lib/pacman/db.lck
	sudo arch-chroot $i pacman -Rssun --noconfirm qt{5,6}-{doc,examples}
	sudo btrfs property set $i ro true
done

Thatā€™s IMHO a potentially dangerous thing to do with in batch. It destroys the snapshot cause as a rescue method, especially when doing package related actions.
I would understand a one time usage, as a method of restoring/fixing a specific snapshot, so you can use it to restore your system, when you have no other choice.
To me, it looks like posting the rmrf/* command as an easy partition clean up method. :face_with_head_bandage:

Just an opinionā€¦ :person_shrugging:

2 Likes

I did that just because I am running low on space and it is needed to clean all traces of a file to free up its space if the file is snapshotted.

I get that. Itā€™s just exposed to anyone not understanding the risks.
A disclaimer for the risks might be better than nothing, or anything elseā€¦ :person_shrugging:

6 Likes

:warning: Important note:
It has been pointed out that updating the mirrorlist should only be done immediately before refreshing packages and fully updating the system. Deviating from this practice, such as setting up a service like described below, can have unwanted consequences and is officially not advised.

I like the convenience of having the mirrorlist refreshed automatically before running an update, and I appreciate the thirty seconds or whatever it takes is very fast considering what is happening, but sometimes if I am waiting for the update it still feels like it is taking a long time.

I turned the process into a service that runs at boot, in the background where I donā€™t have to sit there waiting for it to finish.

First make a script to update the mirrorlist:

micro /usr/local/bin/refresh_mirrorlist
#!/bin/bash
set -e

# Refresh mirrorlists
if [ -x /usr/bin/rate-mirrors ]; then
    echo -e "\n\033[1;33m-->\033[1;34m Refreshing mirrorlists using rate-mirrors, please be patient..\033[0m"
    # Refresh mirrorlist and make sure it actually contains content. There is a bug in rate-mirrors that creates empty files sometimes.
    MIRRORLIST_TEMP="$(mktemp)"
    rate-mirrors --allow-root --save=$MIRRORLIST_TEMP arch --max-delay=21600 > /dev/null \
    && grep -qe "^Server = http" "$MIRRORLIST_TEMP" && install -m644 $MIRRORLIST_TEMP /etc/pacman.d/mirrorlist && DATABASE_UPDATED=true || { echo -e "\033[1;31m\nFailed to update mirrorlist\033[0m"; }
    rm -f $MIRRORLIST_TEMP
    $INT
elif [ -x /usr/bin/reflector ]; then
    echo -e "\n\033[1;33m-->\033[1;34m Refreshing mirrorlists using reflector, please be patient..\033[0m"

    reflector --latest 5 --age 2 --fastest 5 --protocol https --sort rate --save /etc/pacman.d/mirrorlist \
    && $INT && DATABASE_UPDATED=true || { echo -e "\033[1;31m\nFailed to update mirrorlist\n\033[0m"; }
    $INT
fi

:point_up: I did not write that, Iā€™m pretty sure TNE didā€“I just copied it right out of /usr/lib/garuda/garuda-update/main-update, knocked off two && $PACMAN -Syy, and left the rest alone.

Make it executable:

sudo chmod +x /usr/local/bin/refresh_mirrorlist

Set up the service:

micro /etc/systemd/system/refresh_mirrorlist.service
[Unit]
Description=Refresh Mirrorlist
Wants=network-online.target
After=network-online.target nss-lookup.target

[Service]
Type=oneshot
ExecStartPre=/bin/bash -c 'until host archlinux.org; do sleep 1; done'
ExecStart=/usr/local/bin/refresh_mirrorlist

[Install]
WantedBy=multi-user.target

The ExecStartPre line was added just to make sure names are actually resolving before starting rate-mirrors. Without it, even though I have After=network-online.target nss-lookup.target the service was usually working fine, but every once in a while rate-mirrors would fail because it couldnā€™t resolve something.

Maybe the daemon isnā€™t actually ready the exact millisecond it claims it is, or perhaps there is a race condition with another serviceā€¦or maybe something else. :man_shrugging: There are probably a hundred other ways to resolve this issue, but I like this method and it is simple.

Enable the service:

sudo systemctl enable refresh_mirrorlist.service

Finally, edit the Garuda Update config so refreshing the mirrorlist is skipped when running updates.

micro /etc/garuda/garuda-update/config

:point_up: You have to make that directory first if you havenā€™t yet. More about this config file here: Garuda Update | Garuda Linux wiki

Add to the config file:

SKIP_MIRRORLIST=1

After a reboot you can confirm your mirrorlist has been refreshed by running
systemctl status refresh_mirrorlist.service, or take a peek at the timestamp in /etc/pacman.d/mirrorlist.

If for some reason you need to refresh your mirrorlist in between reboots, you can just run the service (systemctl start refresh_mirrorlist.service).

Thatā€™s about it! A fresh mirrorlist at every boot, and no waiting while you run your updates. :smile:

6 Likes

This is potentially dangerous.
You may do what you like with your system, but, please, donā€™t advise others to do this.

There is a lot of misunderstanding with when and why mirrorlists need to be recalculated.
The most dangerous part is assigning this important system task to an automated procedure.
When you change your mirrorlist(s), for any reason, you need to refresh packages and immediately update the whole system.
Since you canā€™t update your system unattended, you can not automatically create a new mirrorlist.

If you want better options to ensure your mirrorlist(s) are always proper (not updated), try safesync (it is recently added in chaotic).
Because safesync has a lot of functionalities, I suggest you study and experiment with it (if you actually want to safeguard your system).
I would appreciate any feedback, either in a new topic here, or at GitLab issues. :wink:

5 Likes

Thanks Petsam, it sounds like I have more reading to do! :laughing: I will check out SafeSync like you suggested; I appreciate the tip, and thanks again for the guidance.

I edited the post above to add a dislaimer noting that it is reckless as you mentioned, but if you think it would be better to take it down altogether I wouldn't take it personally or anything. :slightly_smiling_face:

4 Likes

We are working hard for your needs!

Any corrections are appreciated, even language improvements (I am a poor English speakerā€¦) :cry:

6 Likes

I created a simple password generator, because I couldn't find one working similarly to the one in KeePassXC. Results are looking good too.

I tried to do this in Bash previously, but I suck at it so this is lua instead.

Seeded using time, because /dev/random is hard

https://server.chonkyrabbit.eu/files/Scripts/passwordgen.lua

screenshot-20221009-010209

1 Like

Cant remember the KeepassXC generator but I like the one from Bitwarden.

Thats my new forum password :wink:

1 Like

Give email please k thx

https://start.garudalinux.org/

Seems my joke might have gone over your head lol. Nevermind

List all hooks of a package and the packages depending on it - Useful for pacman -Rns cases.

I created this because I removed snap-pac-grub yesterday, which also uninstalled snap-pac, which uses a hook that removes all snapshots on removal. I only noticed this after it finished deleting all of them.

I wanted to include this into pacman, thus the interaction prompt at the bottom, but this seems to require an alias which I still need to figure out

#!/usr/bin/bash

#grep does not like \s+ for reasons

PACKAGES=$(pacman -Qi "$1" 2>/dev/null | grep -Po "(?<=Name            :).*")
PACKAGES=$PACKAGES$(pacman -Qi "$1" 2>/dev/null | grep -Po "(?<=Required By     :) .*")
PACKAGES=$PACKAGES$(pacman -Qi "$1" 2>/dev/null | grep -Po "(?<=Depends On      :) .*")

echo "The following hooks exist:"

for PKG in $PACKAGES; do
	pacman -Ql "$PKG" 2>/dev/null | grep -Po ".*\.hook"
done

if [[ ! $(echo "$PACKAGES" | wc -w) -eq 1 ]]; then
	echo "Press any key to continue..."
	read -rsn1
fi
2 Likes

The script is assuming user locale (LANG) is English.
It would be a good habit for all the English+ coders to provide code for non-English users as well, or at least to make their code locale agnostic. :wink:

Usually, it can be done by adding LANG=C at the beginning of the script or a command.

6 Likes

GRUB menu entry to boot the .iso from hard disk (thanks to the included loopback.cfg):

menuentry "Garuda Sway ISO" {
    iso_path="/boot-isos/garuda-sway-linux-zen-221019.iso"
    export iso_path
    search --set=root --file $iso_path
    probe -u -s rootuuid $root
    export rootuuid
    loopback loop $iso_path
    root=(loop)
    configfile /boot/grub/loopback.cfg
    loopback --delete loop
}

Note that the disk is GPT and the .iso is on an ext4 partition.

What for?

Well, in my case, because my laptop BIOS doesn't boot from USB and it has a faulty DVD drive.
Not so sure about general usefulness to be honest, but here it is anyway.

3 Likes

Christmas present: file picker of broot.
When path completion is not enough or typing br is too much.

~/.config/fish/conf.d/broot_keybind.fish
function fish_commandline_ensure_space_before
    #test (commandline -C) -gt 0; or return
    commandline -c | string sub -s -1 -l 1 | string trim | string length -q; or return
    commandline -i ' '
end
function fish_commandline_ensure_space_before
    #test (commandline -C) -gt 0; or return
    commandline -c | string sub -s -1 -l 1 | string trim | string length -q; or return
    commandline -i ' '
end

function fish_commandline_ensure_space_after
    test (commandline -C) -gt 0; and commandline -b | string sub -s (commandline -C) -l 1 | string trim | string length -q; or return
    commandline -i ' '
end

function fish_commandline_insert
    #commandline -rs '...' # what is selection anyways?
    commandline -i (string join ' ' $argv)
end

function _broot_ # NOTE: adapted from `br`
    set -l s
    set -l cmd_file (mktemp) # TODO: trap?
    if broot --outcmd $cmd_file $argv
        read --local --null cmd < $cmd_file
        eval $cmd
        set s $status
    end
    rm -f $cmd_file
    return $s
end

function _broot_file_picker_impl
    # TODO: avoid the `while read`, but how?
    function string_escape_ifneeded
         while read -l -L line
            string match -q -r '[ \'"$%!]' -- "$line" # TODO: better detection
                and set line (string escape -- "$line")
            printf '%s\n' "$line"
         end
    end

    set -l sed_cmd '/^$/d' # remove empty lines (but where do they come from?)
    contains -- '-s' $argv; and set -- sed_cmd $sed_cmd 's|^'"$HOME"'|~|' 's|^'"$PWD"'|.|'
    contains -- '-d' $argv; and set -- sed_cmd $sed_cmd '/^[.~]$/d'

    # NOTE: `_broot_` and `br` both work
    set -l output (_broot_ |string split0 |string trim -r)

    # NOTE: the assumption that only pathnames are returned is wrong.
    #       external verbs may print anything. sanity check:
    test -e "$output[1]"; or return

    string join \n $output \
    | sed -E (string join ';' $sed_cmd) \
    | string_escape_ifneeded
end

#FIXME: when broot is started by the keybind, some external verbs are broken
#       e.g. micro cannot save (?) and file contents are returned on leave.
function _broot_file_picker
    fish_commandline_ensure_space_before
    fish_commandline_insert ( _broot_file_picker_impl -s -d )
    fish_commandline_ensure_space_after
end

bind \ef _broot_file_picker # alt-f

~/.config/broot/file_picker.hjson
{   verbs: [
        { # exit copying selected path to cliboard
            key: ctrl-c
            external: "wl-copy {file}"
            leave_broot: true
        }

        { # print the path of the single selected file (then inserted into commandline)
            key: alt-f
            cmd: ":print_path"
            panels: [tree, fs]
        }
        { # print the path of all the staged files (then inserted into commandline)
            key: alt-g
            cmd: ":open_staging_area;:panel_right;:print_path"
            panels: [tree, fs]
        }

        { # quickly stage file (hide staging area and scroll down)
            key: alt-s
            cmd: ":toggle_stage;:close_staging_area;:line_down"
            panels: [tree, fs]
        }

        { # toggle staging area
            key: ctrl-s
            cmd: ":toggle_staging_area"
        }
        { # open and focus staging area
            key: ctrl-alt-s
            cmd: ":open_staging_area;:panel_right"
            panels: [tree, fs]
        }

        { # quit on alt-q (ergonomics)
            key: alt-q
            cmd: ":quit"
        }

] }

Default keybinds:

  • In fish:
    alt-f run broot
  • In broot:
    alt-f leave picking one pathname
    alt-g leave picking staged pathnames
    alt-s stage item and move down
    ctrl-c leave copying one pathname to the clipboard
    (plus some other unnecessary ones)

By default, if the returned path starts with $HOME or $PWD it is shortened to either ~ or ., and if it results in exactly ~ or . it is removed (options -s and -d somewhere).
This way, two alt-f in a row open and close broot without touching the commandline.

edit: found a problem, worked around but not fixed.
When starting broot by the fish keybind, some external verbs are broken (and print out stuff that would end up in the commandline).
For instance, micro cannot save (but works fine if starting broot with the br alias).

4 Likes

A simple and dirty way to convert* images to your current display resolution.
it probably has bugs like that one night I stayed camping near the ocean... anyway

#!/bin/bash
#my head against the keyboard

usage (){
	echo "This is a simple and weak script to convert images to the current screen resolutoin"
	echo "Synopsys: image_convert [file1] [file2] [file3] ..."
	echo "New images will be created with the resolution appened to the end of the file, and will be saved to the current directory"
}

# we need the current screen resolution
screen_resolution=$($(which inxi) -G | grep -oP '[0-9]{1,4}x[0-9]{1,4}' -)  #this is horrible
echo "detected resolution $screen_resolution, if this is incurrect, press ctrl-c NOW!"
sleep 5

#converting to current resolution
for arg in $@
do
	convert -verbose $arg -resize $screen_resolution ${arg%.*}_$screen_resolution.png
done
5 Likes