Post your handy utility scripts!

Mostly because I’m not a programmer, and therefore not particularly good at writing scripts. Prior to writing this I used to keep a list of programs and copy paste it, e.g. yay -S pkg1 pkg2 pkg3 pkg4, but far too often one pkg would fail to build causing the entire process to stop, forcing me to rewrite it and cut whatever didn’t build and do it again. Therefore, when writing this I wanted to do them one by one. Having said that, I have not had a pkg fail to build with this yet so I’m not entirely sure it even solves the problem I was having. For now, it does what I wanted it to, and doesn’t take long to do so.

If you want to improve upon it, you are of course free to do so.

Batteries don’t last for ever - and we all know there is a backside to run your laptop always on.

But when you plug the charger you forget it - then you charge to 100% and that is not ideal - with this script you get notifications when it is time to unplug.

From another place I got a link to a script - which I then refactored to fit my temper and the result was below script.

#! /bin/bash
# Script to notify when battery is outside levels - time to plug charger.
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <>.#
# Source:
# 2021-11-27
# 2021-11-28 revised - checks not updating
#                    - fix variable check on all levels

set -eu

# dependency check
if ! [[ "$(which notify-send)" =~ (notify-send) ]]; then
	echo "Please install libnotify to use this script.\n"
	echo "   sudo pacman -S libnotify"
	exit 1
if ! [[ "$(which acpi)" =~ (acpi) ]]; then
	echo "Please install acpi to use this script.\n"
	echo "   sudo pacman -S acpi"
	exit 1

# check interval (seconds)

# example battery levels
# these leves are not based on scientific evidence
# you are required to adjust as appropriate for your device
MIN_BAT=10     # low water mark
MAX_BAT=60     # high water mark

	echo $(cat /sys/bus/acpi/drivers/battery/*/power_supply/BAT?/status)

    echo $(acpi|grep -Po "[0-9]+(?=%)")

# primary loop
while true ; do

	if [ $(get_bat_percent) -le ${MIN_BAT} ]; then # Battery under low limit
 		if [[ $(get_plugged_state) = "Discharging" ]]; then # plugged
 		    notify-send "Battery below ${MIN_BAT}. Time to plug adapter"
	if [ $(get_bat_percent) -ge ${MAX_BAT} ]; then # Battery over high limit
 		if [[ $(get_plugged_state) = "Charging" ]]; then # plugged
 			notify-send "Battery above ${MAX_BAT}. Time to unplug adapter"
	sleep ${INTERVAL} # Repeat every $INTERVAL seconds


Now, if only I could make it run on my phone. The laptop I have is pretty well dead when not plugged, because I didn’t have this script! (at least partially - it’s really a old Toshiba that My sister ran Win 7 on, before I dual booted Arch on it! - because it’s non-UEFI machine and I wanted to try the Arch way without UEFI))

I would think you could make it work on a pinephone :slight_smile:

Quite probable - but I have a Samsung A32. I just would like for it work for longer than the previous ones I have had…which have lived a life of occasional total discharge, and too frequent charge to 100% (thus shortening their battery life). I could get by quite happily with my S3 - or my A5(2017) - if they would still charge up and hold it satisfactorily! Not much smart needed in my phone - once or twice a year needing to navigate with it, 4 times a year looking something up on the net, and frequent use of Cool Reader is about it beyond taking or making a call!

It can’t just be because I’m old, can it? :grin:

I have seen AccuBattery recommendations but I haven’t really used it that much to give an “objective” :wink: review. Might be worth some research.

If research consists of reading about it… :grin: It actually looks well worth trying it out - and thanks! Pretty much what I wanted by the description… although I wish it could actually stop the charging at the specified percentage, rather than just warn about it. Got to try it to see how it goes though…

1 Like

This would be great. I just installed AccuBattery on my Samsung S8, we’ll see how it goes. I normally leave it plugged in overnight, so I’m worried about the alarms then. I’m not sure waking up in the middle of the night every night to unplug my phone for better battery life is a good trade off. Time will tell.

Edit: There is a do not disturb setting in the app, so you can set it to not alarm in a specific time range. I slept well last night :slight_smile:

1 Like

If your phone supports it, certain custom ROMs come with the feature of stopping the charging at a specified percentage. I have CrDroid on my Oneplus 8t and it works flawlessly.

1 Like

EndeavourOS, in common with other Arch-based distros, nearly always has updates awaiting - which means a notifier isn’t as useful as it might be for some. For others, they don’t like the ‘attention-getting’ that a notifier specializes in. Sometimes you want to know more about the pending updates, though, and you usually want to know NOW!.

I had these scripts (actually implemented at the moment as bash functions) for a while, but they have been upgraded a bit lately (with some expert help).

Basically, on demand (that means when you call their name from a terminal :grin:) you will get either a full count on what’s waiting (repos and AUR) with upcnt - or you get a formatted list of all awaiting updates, both repo and AUR. You also get a bonus with upls - it will tell you if theses updates are likely to require a reboot! This can be useful in deciding whether to update NOW, or at the end of your session…

Here they are:

# Function to count available updates

upcnt() {
# create vars

# count AUR and pacman updates
NEWAUR=`yay -Qua | wc -l`
NEWPKG=`checkupdates | wc -l`

# output RESULT
if [[ ${NEWPKG} == 0 && ${NEWAUR} == 0 ]]; then
	RESULT="System up-to-date"
	RESULT=$NEWPKG" Repo pkgs + "$NEWAUR" AUR pkgs need updating"
echo $RESULT
# Function to display listing of available updates
# will also let you know if a reboot is likely to be needed

upls() {
    local updatesAUR=$(yay -Qua)
    local updates=$(checkupdates)

    # output RESULT
    if [ -n "$updates" ] || [ -n "$updatesAUR" ]; then
		echo "Repo packages"
		echo "-------------"
		     echo "$updates"
		} | column -t -N Name,Current,"->",New
        echo " "
        if [ -n "$updatesAUR" ]; then
            echo " "
            echo "AUR Packages"
            echo "------------"
                echo "$updatesAUR"
            } | column -t -N Name,Current,"->",New

 	#check for core system packages
	RUN_KERNEL=$(cat /proc/version | sed 's|.*(\([^@]*\)@archlinux).*|\1|')

	echo " "
	echo $updates | grep -q ${CHKLINE} && echo "Reboot will be recommended due to the upgrade of core system package(s)." || echo "No reboot recommended after this update."
        echo "No pending updates..."

As with any bash function, just paste it into your ~/.bashrc file - or into any such file that .bashrc calls (perhaps .bashrc-personal or .bash-functions?). Or, you could very easily turn them into scripts if you prefer. Enjoy!


True. One of the original ideas behind the eos-update-notifier was to help newcomers (i.e. not knowing how or when to update) keep the system updated, instead of having them run a system without updates for a long time.
Note that originally we had only the offline install…

Naturally, more experienced users don’t need it (and even might be slightly annoyed about it), but in fact I’m letting the eos-update-notifier run on a daily schedule.

Just a matter of taste… :wink:

1 Like

Actually I’m much worse than most experienced users - I have a vertically smooth scrolling list of coming updates on at all times (when an update is pending - which is nearly always), and a count of how many await updated on screen as well. And I STILL have the functions at hand! :grin: (sometimes the scroll is too slow, and it doesn’t tell me if a reboot is coming…)

Maybe you need a wihle loop of:

while true ; do


Seriously, your idea of having to know in advance if a reboot is recommended or not is great!

Someone on a tyhread I can’t find now was talking about a problem they had with updating and NOT rebooting when they should… so I thought I should add that in. Turns out I like it!

Now if I could find that thread, I could link in this one for them…

I created this script for use with a systemd user service for accessing a samba share without implementing any system wide changes.

The script - do remember to run chmod +x on the script file

#! /bin/bash
# Script for mounting and unmounting a configured samba share
#  Depends on `smbclient` and `gvfs-smb`
#  Customize the variables as needed
#  - Symlinks are located in designated folder (default: $HOME/SMBLinks)
#  - Symlink can be named  (default: $SHARENAME)
#  - Using `-u` argument will unmount and remove the symlink
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <>.
# @linux-aarhus -

# your samba server's hostname or IP address

# the share name on the server

# symlink name

# symlink is placed in this folder


SCRIPTNAME=$(basename "$0")

# check argument $1
if [[ "$1" == "-u" ]]; then
    # remove symlink
    # unmount share
    gio mount -u "smb://$HOST/$SHARENAME"
elif [[ $1 != "" ]]; then
    echo ":: $SCRIPTNAME v$VERSION"
    echo "==> invalid argument: $1"
    echo "Usage: "
    echo "  mount SMB : $SCRIPTNAME"
    echo "  umount SMB: $SCRIPTNAME -u"
    exit 1

# mount command
gio mount "smb://$HOST/$SHARENAME"

# easy reference to gio mount point

# create the subfolder
if ! [ -d "$SYMLINKS" ]; then
    mkdir -p "$SYMLINKS"

# use --force argument to suppress warning if link exist

:spiral_notepad: Note:

  • The user service is assuming the above script is located in the service folder.
    Adjust naming accordingly.
  • The service file depends on the credentials has been stored in your keyring.
    Open your file manager’s location bar and input
    Then when prompted store your credentials.
Description=GIO mount smb share-name

ExecStop=/home/%u/.config/systemd/user/ -u


Here’s a small script I use to transform my totally obsolete Windows Phone into a quality webcam. It should work with any phone really (iOS, Android etc) provided you install an app on the phone which streams video accessible by IP. (I’d search “IP cam” in the app store on the phone)

#group the elevated privileges commands
pkexec bash -c "\
modprobe v4l2loopback devices=1 video_nr=10 card_label='VirtualCam' exclusive_caps=1; \
modprobe snd-aloop index=10 id='VirtualMic'; \
#non elevated privileges commands
pacmd 'update-source-proplist alsa_input.platform-snd_aloop.0.analog-stereo device.description="VirtualMic"'
notify-send -t 5000 --icon=camera-video "Virtual Camera" "Camera now streaming" 
ffmpeg -hide_banner -loglevel error -an -probesize 32 -analyzeduration 0 -listen 0 -i http://user:pass@192.168.0.xx:8080/mjpeg -vf format=yuv420p -f v4l2 -vcodec rawvideo /dev/video10  ; notify-send -t 5000 --icon=camera-video "Virtual Camera" "Camera stopped streaming" ;

You’d need to replace http://user:pass@192.168.0.xx:8080/mjpeg with the stream URL provided by the streaming app on your phone. Keep in mind this is not intended to be a secured stream, but if you’re the only one using the network it should be good enough to casually use as a webcam.

The script requires package v4l2loopback-dkms to be installed.

I’m running the script from a launcher in XFCE panel (in non-terminal mode) hence the system notifications to let me know when the streaming is on and off again. (If the streaming fails the last notification is still triggered, letting me know the stream is off).


To cut online video from youtube/vimeo or other sources.

ytdlcut ()
ffmpeg -ss "$2" -i "$(youtube-dl -f "bv*[height<=?1440]" -g --youtube-skip-dash-manifest $1)" -t "$3" -c copy "$(echo "$(youtube-dl -e $1)" | sed 's/[^a-zA-Z0-9 ]//g')-cut.mkv"

Switched to yt-dlp recently, but hasn’t become muscle memory yet. :smile:

This uses yt-dlp. Takes 3 input arguments. 1st is URL, 2nd start time, 3rd is Duration. Output file is in pwd. Change the script to your liking. :grin:

I started the script to handle the recurring tasks on my server:

This is a little script that scans all the .jpg files from current working directory and then moves “Landscape” (width >= height) to a destination folder. Does this using identify which makes things more efficient if current directory is a network dir ( say gdrive or mega) and destination is local.

for i in *.jpg ; do width="$(identify -format '%w' "$i")" ; height="$(identify -format '%h' "$i")" ; if [[ $width -ge $height ]] ; then mv -v "$i" /home/username/destination/ ; else echo "Not Landscape Orientation" ; fi ; done
1 Like

For sway - Screenshot button with optional delay (requires pysimplegui):

#!/usr/bin/env python

import PySimpleGUI as sg
import time
from datetime import datetime
import os


layout = [[sg.Button("Screenshot", button_color=("red", "black"), size=(13, 1), font=("Noto Sans Bold", 11)),
           sg.Text('Delay:'), sg.InputText('0',size=(4,1),font=("Noto Sans Bold", 11))]]

window = sg.Window("Grim-SS", location=(800, 530), alpha_channel=1,
                   keep_on_top=True, no_titlebar=True).Layout(layout).Finalize()

now =
datestr = now.strftime("~/Pictures/grim/%Y%m%dT%H:%M:%S.png")

while True:
    event, values = window.Read()
    if event in (None, 'Exit'):

    if event == 'Screenshot':
        os.system("grim " + datestr)
1 Like