Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

Share your Debian SCRIPTS

Here you can discuss every aspect of Debian. Note: not for support requests!
Message
Author
User avatar
Head_on_a_Stick
Posts: 14114
Joined: 2014-06-01 17:46
Location: London, England
Has thanked: 81 times
Been thanked: 132 times

Re: Share your Debian SCRIPTS

#21 Post by Head_on_a_Stick »

Not a script, just a function I place in my shell initialisation file:

Code: Select all

function achroot {
   for i in proc sys dev{,/pts} ; do
      doas mount --bind /$i "$1"/$i
   done
   doas chroot "$1" /bin/su -
   for i in proc sys dev{/pts,} ; do
      doas umount "$1"/$i
   done
}
It's a simpler version of arch-chroot(8) that can be run on a mountpoint, for example:

Code: Select all

$ doas mount /dev/sda1 /mnt
$ achroot /mnt
Unlike arch-chroot(8) it arrives at a login shell so the files in /etc/profile{,.d/*} are all sourced correctly and PATH works as expected.
deadbang

user6c57b8
Posts: 19
Joined: 2022-05-31 16:19
Has thanked: 5 times

Re: Share your Debian SCRIPTS

#22 Post by user6c57b8 »

Who needs a catch-everything libapt command when you can have a catch-everything cheating/reference program?

I call it apt-easy or apt-reference or apt-safe?

Code: Select all

#!/bin/bash

#this is a 10%-31% comprehensive debian package management reference.
#see the man packages for apt apt-cache apt-file apt-get apt-mark dpkg dpkg-query 
#and debian-reference-en for further inquiry.

#This program just uses `grep` and `egrep` as the only external commands.
#The rest is pure bash `echo`, `test` 


#run with `bash -n` (lint/safe-run) first if you make any changes
#just to make sure the quotes don't mess up

#somebody better make this a HEREDOC...although it'll make the source -3% easier to read.

if [ -z "$1" ]; then
echo '
apt-safe $command

add-repository   - Add entries to apt sources.list
auto             - Set this installed $package_name to be auto-removed (ie. assuming you went `sudo apt autoremove`) iff the explicitely installed (ie. `sudo apt install $explicitely_installed_package`) is `sudo apt purge $explicitely_installed_package`
autoclean        - Erase downloaded archive files from /var/cache/apt/archives/*.deb basically except for the ones that are identical to the ones in your live repository /etc/apt/sources.list*
autopurge        - Remove packages with their configuration files and automatically remove all unused packages (always good after a good `sudo apt purge $package_name` or `sudo dpkg --remove $package_name`)
autoremove       - Remove automatically all unused packages (always good after a good `sudo apt purge $package_name` or `sudo dpkg --remove $package_name`)
autosourceslist  - Generate an automated sources.list file that selects the fastest mirror to `sudo apt install` from
build            - Download source code for a package into current directory, extract, and build it. `sudo apt builddep $package_name` (? or is it source name?) (to get the source-building-dependency packages necessary a priori building otherwise hope for the best)
build-dep        - Configure build-dependencies for source packages; to build source code you will require the necessary packages -- they shall be installed
changelog        - View a packagez changelog
check            - Verify that there are no broken dependencies; same as `sudo apt -f install` (with no other arguments)
clean            - Erase downloaded archive files from /var/cache/apt/archives/*.deb basically
contains         - List packages (that you already have installed) containing a file (eg. `dpkg -S /usr/bin/apt`) (exact filename)
contains-repo    - List packages (that are anywhere in your live repository) containing a file (eg. `apt-file search "/usr/bin/apt"`) (filename substring match)
content          - List filelist contained in currently installed $package_name
deb-install      - Install a .deb package file (does not install dependencies automatically. For that you will need to go `sudo apt -f install` to fix the dependency mess)
depends          - Show Depends/Recommends/Suggests information for a $repo_package_name
dist-upgrade     - Upgrade the system by removing/installing/upgrading packages (I have honestly never used this before)
download         - Download the .deb file for a $package_name into the current working directory
download-all     - Download the .deb file for a package + all packages that are required that you do not have installed (recursive-dependencies)
edit-sources     - Edit /etc/apt/sources.list with your preferred text editor
dselect-upgrade  - Follow dselect selections
fix-broken-dep   - Try to fix currently installed packages including retrying to install packages that were partially installed (especially if you do `sudo dpkg -i package_name_whatever.deb`)
full-upgrade     - Same as "dist-upgrade"
held             - List all held packages
hold             - Prevent this installed package (from package name) from being installed, upgraded, or removed
install          - Install/upgrade packages
list             - List package name/version/architecture based on a package name (can use "*" as a wildcard) that exists in your /etc/apt/sources.list* repositories (same as `apt-cache list`)
listfiles        - List files in a package
listallpkgs      - List all installed packages (with a one-lined description for each package) (pipe to grep to search for a package name)
manual           - Prevent this $installed_package_name from being `sudo apt autoremove` if it was "auto" installed from an explicitely installed package (ie. from `sudo apt get install $explicitely_installed_package && sudo apt purge $explicitely_installed_package`) as dependencies
moo              - An apt/apt-get easter egg; display a cow with a "moo"
pkgurl           - Show the URL (basically) where the $repo_package_name is located (from within the places configured in /etc/apt/sources.list*)
purge            - Remove $installed_package_name and their configuration files
recommends       - List the recommended packages of all "manually" (ie. explicit apt install or dpkg -i) installed packages
rdepends         - Show reverse dependency information for a package "what else would make $this_package_name_in_repo be installed"
reinstall        - Download and (possibly) reinstall a $currently_installed_package
remove           - Remove packages (as a list of one or more package names you have currently installed)
searchforfile    - $Search_for_a_file in all packages in your live repository /etc/apt/sources.list*
show             - Display detailed information about a package that doesnt have to be already installed.
showhold         - Same as "held"
showmanual       - Show packages that you have explicitely `sudo apt install $package_name` OR `sudo dpkg -i $deb_file #package`
showsrc          - Display all the source package records that match the given package name (requires you have a "^deb-src" line in your /etc/apt/sources.list* I am 90% sure..it looks virtually identical to the "^deb" line)
source           - Download source archives to current directory, apply all patches, extracts the source to a directory
sources          - Same as "edit-sources"
unhold           - Unhold a package
update           - Download lists of new/upgradable packages
upgrade          - Perform a safe upgrade
version          - Show the installed version of a package
' | egrep --color '^[a-z\-]+'
else
echo '
`apt-cache` depends rdepends stats list show
`apt-cache policy` pkgurl
`apt-file search` contains-repo
`apt` depends download list moo show showsrc source 
`apt-mark` showhold showmanual
`dpkg -L` content
`dpkg -l` listallpkgs
`# I have a bash "one-liner" that can do this, request as necessary` recommends
`dpkg-query -f "\${Version}" -W` version
`dpkg -S` contains
`sudo apt` autoremove --reinstall install autoclean build-dep clean dselect-upgrade edit-sources full-upgrade purge remove update upgrade
`sudo apt --build source` build
`sudo apt --purge autoremove` autopurge
`sudo apt edit-sources` sources
`sudo apt -f install` fix-broken-dep
`sudo apt full-upgrade` dist-upgrade
`sudo apt-get` check
`sudo apt install apt-file && apt-file list` listfiles
`sudo apt install apt-file && apt-file search` searchforfile
`sudo apt install aptitude && aptitude` changelog
`sudo apt install aptitude && sudo aptitude` reinstall
`sudo apt install apt-rdepends && man apt-rdepends` download-all
`sudo apt install netselect-apt && sudo netselect-apt` autosourceslist
`sudo apt install software-properties-common && man add-apt-repository` add-repository
`sudo apt-mark` hold unhold manual auto
`sudo dpkg -i` deb-install
' | grep --color "$1"
fi

User avatar
fabien
Forum Helper
Forum Helper
Posts: 604
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 60 times
Been thanked: 141 times

Re: Share your Debian SCRIPTS

#23 Post by fabien »

Head_on_a_Stick wrote: 2022-06-15 06:37It's a simpler version of arch-chroot(8) that can be run on a mountpoint
Thanks @Head_on_a_Stick, sorry for the delay. Could you please explain a little bit why you are using this, what does it allow to do?

User avatar
Head_on_a_Stick
Posts: 14114
Joined: 2014-06-01 17:46
Location: London, England
Has thanked: 81 times
Been thanked: 132 times

Re: Share your Debian SCRIPTS

#24 Post by Head_on_a_Stick »

It just sets up a chroot with the API filesystems mounted automatically and then removes the mounts afterwards. I use it to get login shells in other installed systems, containers or images.
deadbang

User avatar
fabien
Forum Helper
Forum Helper
Posts: 604
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 60 times
Been thanked: 141 times

Re: Share your Debian SCRIPTS

#25 Post by fabien »

updated schow-pkg from 3.2 to 4.0 (Added ability to use alternative sources, see screenshots. Plus some improvements.)

User avatar
fabien
Forum Helper
Forum Helper
Posts: 604
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 60 times
Been thanked: 141 times

Re: Share your Debian SCRIPTS

#26 Post by fabien »

Since schow-pkg can now query alternative repositories, apt-cache search functionality is now supported.
updated schow-pkg from 4.0 to 4.1 (Added search function).

user6c57b8
Posts: 19
Joined: 2022-05-31 16:19
Has thanked: 5 times

Re: Share your Debian SCRIPTS

#27 Post by user6c57b8 »

updated apt-show-BIN-files-from-manually-installed-packages.sh from 1.0 to 2.0 (changes: added blue color to the output command.) (open bugs: some people reported some bin paths are invalid bin paths.)

User avatar
fabien
Forum Helper
Forum Helper
Posts: 604
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 60 times
Been thanked: 141 times

Re: Share your Debian SCRIPTS

#28 Post by fabien »

updated schow-pkg from 4.1 to 4.2 (Added virtual packages providers resolution.)

User avatar
Bloom
df -h | grep > 90TiB
df -h | grep > 90TiB
Posts: 503
Joined: 2017-11-11 12:23
Been thanked: 26 times

Re: Share your Debian SCRIPTS

#29 Post by Bloom »

I use a script musget to fetch music from Youtube and convert it to either a single song or a full album with all tracks numbered properly.
It uses yt-dlp, which you will need to install.

Code: Select all

#!/bin/bash
Ddir="$HOME/cdrip/YT" # this is my local directory where I rip the music into
Mdir="$HOME/Muziek/Lossless/00 HighDef/YT (opus-aac 🡆 96k flac)" # this is on my NAS where all music files have to be to be used by music streamers in the house. 'Muziek' is Dutch for 'music'.
Stamp="$(date '+%Y%m%d%H%M.%S.%6N')"
LogF="$Ddir/yt_$Stamp.log"
if [[ -n $1 ]]; then
  if [[ $1 == "mv" ]]; then
    # echo Convert YT-downloaded music to flac and move it to proper music directory
    # soundconverter -b "$Ddir" -f flac -q 8 -o "$Ddir/flac"
    # rsync  -vau --progress --stats "${Ddir/flac/YT/}/" "${Mdir}/" && rm -rf ${Fdir/flac/YT}/*
   # I don't do the automatic conversion to flac yet as it seems filenames have to be corrected first in a number of cases.
    xdg-open "$Ddir"
    xdg-open "$Mdir"
  else
    cd $Ddir
    yt-dlp -x --audio-quality 0 "$@"|&tee "$LogF"
    Album=$(grep "Finished downloading playlist"<"$LogF"|cut -d ':' -f 2|awk '{$1=$1};1') #awk is trim function
    Tlist="$(grep "\[ExtractAudio\] Destination:"<"$LogF"|cut -d ':' -f 2|awk '{$1=$1};1')"
    Tracks=$(grep -c . <<<"$Tlist")
    [[ -z $Album || -z $Tracks ]] && Tracks=1
    t1="01"
    (( Tracks > 99 )) && t1="001"
    for t in $(eval echo {$t1..$Tracks}); do
      f="$(sed -n ${t}p <<<"$Tlist")"
      fn="${f// \[*\]/}"
      fn="${fn// (?fficial *)/}"
      (( Tracks > 1 )) && fn="$t $fn"
      if [[ -s "$f" && -n "$fn" ]]; then
        mv "$f" "$fn"
        echo "$f 🡆 $fn"
      else
        echo "***ERROR f=«$f» does not exist or is empty"
        echo -n "fn=«$fn»"
        [[ -z $fn ]] && echo " is empty" || echo .
      fi
    done
    if [[ -n $Album ]]; then
      mkdir "$Album"
      mv -f -- *.{opus,m4a} "$Album"/ 2>/dev/null
    fi
    cd $HOME
    rm -f "$LogF"
  fi
else
  echo "Please provide move command 'mv' or YT-url to download music"
fi


User avatar
sunrat
Administrator
Administrator
Posts: 6382
Joined: 2006-08-29 09:12
Location: Melbourne, Australia
Has thanked: 115 times
Been thanked: 456 times

Re: Share your Debian SCRIPTS

#30 Post by sunrat »

@Bloom why this? -

Code: Select all

(opus-aac 🡆 96k flac)
I see you don't do the conversion in the script, but yt-dlp -x will extract the best quality audio available which is usually opus 48k. Upsampling to 96k will not improve quality. I usually just keep and play the opus files as they sound indistinguishable from any flac files derived from format conversion, play natively in Linux or Android, and are amazingly efficient for size.
If you really want flac files you can use yt-dlp -x --audio-format flac which converts opus to 48k 24 bit flac. Still a waste of space compared to opus with no quality improvement (approximately 10x the size of the opus file it's converted from in one test I did).

The renaming function looks handy. 8)
“ computer users can be divided into 2 categories:
Those who have lost data
...and those who have not lost data YET ”
Remember to BACKUP!

User avatar
Bloom
df -h | grep > 90TiB
df -h | grep > 90TiB
Posts: 503
Joined: 2017-11-11 12:23
Been thanked: 26 times

Re: Share your Debian SCRIPTS

#31 Post by Bloom »

Opus is the sole property of Google, so that's why I'm converting to flac. That's open and free. That it takes a little more space is no problem.
Most upsampling routines introduce a lot of noise in the high frequencies, but mine doesn't. But there really shouldn't be any difference between 48 kHz and upsampled 96 kHz, that's correct.

User avatar
sunrat
Administrator
Administrator
Posts: 6382
Joined: 2006-08-29 09:12
Location: Melbourne, Australia
Has thanked: 115 times
Been thanked: 456 times

Re: Share your Debian SCRIPTS

#32 Post by sunrat »

Bloom wrote: 2022-07-18 09:55 Opus is the sole property of Google,
Not even a little bit true. They use it for Youtube because it's the best codec option.
so that's why I'm converting to flac. That's open and free. That it takes a little more space is no problem.
Opus is open and free. It was developed by a group led by the Xiph foundation.
From https://en.wikipedia.org/wiki/Opus_(audio_format)
As an open format standardized through RFC 6716, a reference implementation called libopus is available under the New BSD License. ... All known software patents that cover Opus are licensed under royalty-free terms.[10] Opus is widely used as the voice-over-IP (VoIP) codec in applications such as Discord,[11] WhatsApp,[12][13][14] and the PlayStation 4.[15]
Opus was proposed for the standardization of a new audio format at the IETF, which was eventually accepted and granted by the codec working group. It is based on two initially separate standard proposals from the Xiph.Org Foundation and Skype Technologies S.A. (now Microsoft). Its main developers are Jean-Marc Valin (Xiph.Org, Octasic, Mozilla Corporation), Koen Vos (Skype), and Timothy B. Terriberry (Xiph.Org, Mozilla Corporation). Among others, Juin-Hwey (Raymond) Chen (Broadcom), Gregory Maxwell (Xiph.Org, Wikimedia), and Christopher Montgomery (Xiph.Org) were also involved.
Bloom wrote:Most upsampling routines introduce a lot of noise in the high frequencies, but mine doesn't. But there really shouldn't be any difference between 48 kHz and upsampled 96 kHz, that's correct.
If there's no difference, why use it when it takes up a lot more space? Upsampling is pointless. Converting a lossy format to a lossless one for no benefit seems futile. Especially when the lossless one at one tenth the size has no perceptible audio difference. It certainly won't restore the bits removed in the lossy encoding process.
And please tell me about your upsampling routine. SoX? I use it for downsampling and it does that very well.
“ computer users can be divided into 2 categories:
Those who have lost data
...and those who have not lost data YET ”
Remember to BACKUP!

User avatar
Zoot
df -h | grep > 90TiB
df -h | grep > 90TiB
Posts: 163
Joined: 2010-01-12 15:27
Location: Ireland
Has thanked: 5 times
Been thanked: 3 times

Re: Share your Debian SCRIPTS

#33 Post by Zoot »

Here's a script I put together which I'm quite proud of. :D

It checks what my home Public IP stepping through a list of external URLs, logs the results, and if a change is identified it emails me the result. It will also send a log file of the IP address throughout the day at the very end of the day so I always will know what my Home IP is if I'm away from home and want to connect to my OpenVPN server to look at my CCTV etc. It saves me the expense of paying for a Static IP from my ISP or purchasing a DDNS service.

It requires curl & mutt as dependencies and also an appropriate muttrc file set up to send the emails.

I run it on my server as a scheduled task every half hour. I like stuff heavily commented so I can go back to it in years to come. Should be easy if anyone wants to dig through it. I don't consider myself a bash scripting expert, so no guarantee it's perfect, but it has worked very well for me for over a year or so now. :)

Code: Select all

#!/bin/bash
###################################
# HOMEMADE DDNS SCRIPT
###################################
# This Script finds the Public IP address from
# the command line. It does this by checking a
# number of URLs that output the IP address of
# a user connected to them in plain text. It is
# intended to be run as a scheduled task.
#
# If the 1st of these URLs can't be contacted or
# don't produce a valid output, it will move on
# to the next URL and so on. If none of them can
# be contacted or give a valid output the script
# will exit.
#
# If a valid IP is detected, it is recorded in a
# logfile. If changes in the public IP are detected
# between successive runs of the script, a notification
# email is sent. Also if the script is ran for the 1st
# time on a particular day, the log of IP addresses
# from yesterday is forwarded by email provided it exists.
#
# With this configuration, assuming internet access
# and that the email server is contactable and works
# it should always be possible to correctly determine
# the public IP address if DDNS is to fail.
###################################

###################################
# INPUT PARAMETERS
###################################

# Mutt RC Path for Email Notifications
muttrc_path=/Appdata/public_ip/mutt/muttrc

# Email Address to sent notifications to
email_address="email_address"

# Email Body File
email_body=/tmp/find_public_ip_email

# Logfile path
logfile_path="/Appdata/public_ip/logs/"

# IP Check URLs
declare -a ip_check_urls=( "ifconfig.co" "ifconfig.me" "icanhazip.com" "ipecho.net/plain")

######################################################################
######################################################################
# **** NO NEED TO EDIT ANYTHING BELOW THIS LINE... HOPEFULLY!! ****
######################################################################
######################################################################

###################################
# SCRIPT FUNCTIONS
###################################
function sanity_check() {
	###################################
	# Sanity Check
	###################################

	# Check Logfile Directory Exists & is Writable
	if [ ! -d $logfile_path ]
	then
		echo "Logfile Path not found. Exiting..."
		exit
	elif [ ! -w $logfile_path ]
	then
		echo "Logfile Path not writable by user. Exiting..."
		exit

	# Check if mutt is installed
	elif [ -z $(which mutt) ]
	then
		echo "mutt does not appear to be installed. Exiting..."
		exit

	# Check if curl is installed
	elif [ -z $(which curl) ]
	then
		echo "curl does not appear to be installed. Exiting..."
		exit

	# Check the Muttrc file exists
	elif [ ! -f $muttrc_path ]
	then
		echo "muttrc file not found for sending emails. Exiting..."
		exit
	fi
}

function send_ip_change_email() {
	###################################
	# Send IP Change Notification Email
	###################################

	# The IP Address has been found to change, send an email_address
	# send an email to notify the user of this.

	# Generate the Email Body
	echo "Public IP Address change detected..." 	> $email_body
	echo "" 										>> $email_body
	echo "Last IP Address:" $last_ip_address 		>> $email_body
	echo "New IP Address:" $current_ip_address 		>> $email_body
	echo "" 										>> $email_body

	# Send the Email Using Mutt
	mutt -F $muttrc_path -s "Public IP Change Detected" $email_address < $email_body
}

function send_yesterdays_ip_log_email() {
	###################################
	# Send Yesterday's Logfile
	###################################

	# Send Yesterday's IP Address log as an attachment if it is the
	# 1st check of the day

	# Determine the Last ip address from yesterday
	yesterdays_last_ip_address=$( cat $yesterdays_logfile | tail -n 1 | awk '{print $3}')

	# Generate the Email Body
	echo "Yesterdays Public IP address is attached..." 					> $email_body
	echo "Last IP Address was found to be" $yesterdays_last_ip_address 	>> $email_body
	echo ""																>> $email_body

	# Send the email with mutt
	mutt -F $muttrc_path -s "IP Address Log" -a $yesterdays_logfile -- $email_address < $email_body
}

function check_ip() {
	###################################
	# IP Validity Check
	###################################
	# Find IP address from 1st argument
	ip_address=$1

	# 1st check the Length of the IP address
	length=${#ip_address}

	###################################
	# Check 1 - Length of Input String
	###################################
	# Check if the Length is either Less than 7 or Greater than 15
	# for formats like X.X.X.X or XXX.XXX.XXX.XXX
	if [[ $length -lt 7 ]] || [[ $length -gt 15 ]]
	then

		# Length of the IP address isn't valid,
		# Return a 0 value to exit the function
		return 0
	fi

	###################################
	# Check 2 - Structure
	###################################
	# Break the IP address up into its numbers seperated by ".", there
	# should be 4 numbers in total
	byte1=`echo "$ip_address" | xargs | cut -d "." -f1`
	byte2=`echo "$ip_address" | xargs | cut -d "." -f2`
	byte3=`echo "$ip_address" | xargs | cut -d "." -f3`
	byte4=`echo "$ip_address" | xargs | cut -d "." -f4`

	# Check are those numbers empty, 1 or more will be empty
	# if the structure is incorrect
	if [[ -z $byte1 ]] || [[ -z $byte2 ]] || [[ -z $byte3 ]] || [[ -z $byte4 ]]
	then

		# Structure of the input string is not correct as
		# one or more of the numbers are empty. Return 0 to
		# exit the function
		return 0

	fi

	###################################
	# Check 3 - Valid Numbers
	###################################
	if ! [[ "$byte1" =~ ^[0-9]+$ ]]
	then

		# Byte 1 is not a valid number, return 0 to exit the function
		return 0

        elif ! [[ "$byte2" =~ ^[0-9]+$ ]]
		then

			# Byte 2 is not a valid number, return 0 to exit the function
			return 0

        elif ! [[ "$byte3" =~ ^[0-9]+$ ]]
		then

			# Byte3 is not a valid number, return 0 to exit the function
			return 0

        elif ! [[ "$byte4" =~ ^[0-9]+$ ]]
		then

			# Byte4 is not a valid number, return 0 to exit the function
			return 0
        fi

        ###################################
        # Check 4 - Are the Numbers Between 0 & 255
        ###################################
        if [[ $byte1 -lt 0 ]] || [[ $byte1 -gt 255 ]]
		then

			# Byte1 is not between 0 & 255, return 0 to exit the function
			return 0

        elif [[ $byte2 -lt 0 ]] || [[ $byte2 -gt 255 ]]
		then

			# Byte2 is not between 0 & 255, return 0 to exit the function
			return 0

        elif [[ $byte3 -lt 0 ]] || [[ $byte3 -gt 255 ]]
		then

			# Byte3 is not between 0 & 255, return 0 to exit the function
			return 0

        elif [[ $byte4 -lt 0 ]] || [[ $byte4 -gt 255 ]]
		then

			# Byte4 is not between 0 & 255, return 0 to exit the function
			return 0

        fi

        # If none of the above checks failed, then the IP is valid
        return 1
}

function get_public_ip() {
	###################################
	# Get Public IP
	###################################
	# Get the public IP by trying the urls specified in the array
	# ip_check_urls. Each url is tried until a valid output is
	# obtained. If any can't be used to determine the public ip,
	# then the next is moved on to.
	echo "Checking Public IP using the supplied urls..."

	for i in $(seq 0 1 $((check_urls_number-1)) )
	do
		# Check the Public IP using curl
		public_ip=$(curl --silent "${ip_check_urls[$i]}")
		curl_grab_check=$?

		# Check that the curl output is zero, if it is then curl
		# found something, but now we need to check if it's correctly
		# been supplied an IP address
		if [ $curl_grab_check -eq 0 ]
		then
			# Check if the IP is of valid syntax using the above function
			check_ip $public_ip
			ip_check=$?

			# Valid IP was found, break out of the loop and set the public_ip
			# variable correctly
			if [ $ip_check -eq 1 ]
			then
				echo "Public IP succesfully determined to be" $public_ip "using" "${ip_check_urls[$i]}"

				# Set Current IP Address equal to the Public IP
				current_ip_address=$public_ip

				# Break out of the loop
				break

			# Non-Valid IP obtained, try the next url in the array
			else
				# Check if we have tried all urls, if we have
				# then set the IP to "error" and exit. Otherwise move on
				# to the next url to check
				if [ $i -eq $((check_urls_number-1)) ]
				then
					echo "Output from" "${ip_check_urls[$i]}" "also not valid" 
					echo "Errors using all check urls - Cannot determine public IP. Exiting..."
					public_ip="Error"

					# Exit the Script without writing anything to the logfile, this
					# is important as it helps the checks below
					exit
				else
					echo "Output from" "${ip_check_urls[$i]}" "not valid,trying next url..."
				fi
			fi

		# Curl output was non-zero, that means it couldn't contact the url in question
		else
			# Check if we have tried all urls, if we have
			# then set the IP to "error" and exit. Otherwise move on
			# to the next url to check
			if [ $i -eq $((check_urls_number-1)) ]
			then
				echo "Could not connect to" "${ip_check_urls[$i]}"" either."
				echo "Errors using all check urls - Cannot determine public IP. Exiting..."
				public_ip="Error"

				# Exit the script without writing anything to the logfile, this
				# is important as it helps the checks below
				exit
			else
				echo "Could not connect to" "${ip_check_urls[$i]}"",trying next url..."
			fi
		fi
	done
}

function clean_up_logfile_path() {
	###################################
	# Clean Up Log File Directory
	###################################
	find $logfile_path -name "*.txt" -type f -mtime +30 -exec rm -f {} \;
}

function check_for_ip_change() {
	###################################
	# IP Change Check Function
	###################################
	# Investigate the current IP address and the
	# previous IP from the logfile(s) for changes

	###################################
	# Check the Logfile for the Last IP address
	###################################
	# If the Logfile already exists, that means there has been
	# a previous IP address recorded today, if it doesn't then
	# that means this check is the 1st of the day
	###################################
	if [ -f $logfile ]; then

		# Logfile is preset - check last line for the last IP address recorded
		last_ip_address=$( cat $logfile | tail -n 1 | awk '{print $3}')

		# Check if the last & current IP address were obtained successfully,
		# if they were, check if they're not the same
		if [[ "$last_ip_address" != "Error" ]] && [[ "$current_ip_address" != "Error" ]]
		then

			if [[ "$last_ip_address" != "$current_ip_address" ]]
			then
				echo "IP Change Detected!"

				# Send IP Change Notification Email
				send_ip_change_email

				###################################
				# Output the newly obtained IP to the logfile
				###################################
				echo $time_now" : "$current_ip_address >> $logfile

			else
				echo "IP hasn't changed"

				###################################
				# Output the newly obtained IP to the logfile
				###################################
				echo $time_now" : "$current_ip_address >> $logfile
			fi
		fi

	else

		# The logfile doesn't exist, this is the 1st check today,
		echo "1st check today"

		# Check if there is a logfile for yesterday, if something
		# is found then send that via email
		if [ -f $yesterdays_logfile ]
		then
			echo "Found logfile from yesterday - sending via email..."

			# Send Email with above function
			send_yesterdays_ip_log_email

			# We know the logfile from yesterday exists, so the
			# script should have recorded IP addresses from
			# yesterday. Now need to check for an IP change from
			# yesterday.
			echo "Checking for an IP change from yesterday..."

			# Set the last recorded ip address to the value pulled
			# from yesterdays logfile in the above function
			last_ip_address=$yesterdays_last_ip_address

			# Check the two ip addresses to do the comparison are
			# correct. This should be the case with the above checks,
			# but just in case it's not
			if [[ "$last_ip_address" != "Error" ]] && [[ "$current_ip_address" != "Error" ]]
			then
				# Now check if the last and current IP address are NOT the
				# same. If that's the case, send the change notification email
				if [[ "$last_ip_address" != "$current_ip_address" ]]
				then
					echo "IP Change Detected from Yesterday!"

					# Send IP Change Notification Email
					send_ip_change_email
				else
					echo "IP hasn't changed from Yesterday"
				fi
			fi
		else
			echo "Could not obtain IP Address from Yesterday - Logfile not found..."
		fi

		# Output the Public IP into today's logfile if it wasn't flagged as an error
		if [ "$current_ip_address" != "Error" ]
		then
			echo $time_now" : "$current_ip_address > $logfile
		fi
	fi
}

###################################
# SCRIPT START
###################################
# Firstly sanity check that the paths provide are okay
sanity_check

# Find the number of IP Check URLS Specified above
check_urls_number=${#ip_check_urls[@]}

# Find the Current Time
now=`date '+%Y-%m-%d_%H-%M-%S'`
time_now=$(date '+%H:%M:%S')

# Find Todays & Yesterdays date
today=`date '+%Y-%m-%d'`
yesterday=$(date -d @$(( $(date +"%s") - 86400)) +"%Y-%m-%d")

# Construct the Correct Logfile Names for Today and Yesterday
logfile=$logfile_path'ip_log_'"$today"'.txt'
yesterdays_logfile=$logfile_path'ip_log_'"$yesterday"'.txt'

# Use the above defined function to find the Public IP
get_public_ip

# Check for an IP Change
check_for_ip_change

# Clean up the logfile path
clean_up_logfile_path



User avatar
manyroads
Posts: 73
Joined: 2021-04-17 14:27
Has thanked: 1 time
Been thanked: 13 times

Re: Share your Debian SCRIPTS

#34 Post by manyroads »

The following Yad script provides a small System Monitoring panel of ncurses apps. By way of full disclosure, this script also works on arch, devuan and *buntu. :shock:

Image

Code: Select all

#!/bin/bash
# system monitors
# script by ManyRoads https://eirenicon.org

yad --title "System Monitors" --form --width=200 --height=200 --posx=850 --posy=200 --text="<b><u>System Monitors</u></b>" --window-icon=utilities-terminal --image "calligraplan" --image-on-top \
	--buttons-layout=center \
	--window-icon="gtk-quit: exit" \
	--field="<b>atop</b>":fbtn "st -e atop" \
	--field="<b>bpytop</b>":fbtn "st -e bpytop" \
	--field="<b>glances</b>":fbtn "st -e glances" \
	--field="<b>htop</b>":fbtn "st -e htop" \
	--field="<b>lxtask</b>":fbtn "lxtask" \
	--field="<b>ncdu</b>":fbtn "st -e ncdu" \
	--field="<b>nmon</b>":fbtn "st -e nmon" \
	--field="<b>stacer</b>":fbtn "stacer" \
	--field="<b>wavemon</b>":fbtn "st -e wavemon -i wlp1s0" \
	--button=Exit:1
Pax vobiscum,
Mark Rabideau- Prof Genealogist - http://many-roads.com
Linux BLOG https://eirenicon.org
spectrwm,SwayWM,i3wm,hlwm,bspwm,dwm on sid
Linux User #449130

steve_v
df -h | grep > 20TiB
df -h | grep > 20TiB
Posts: 1395
Joined: 2012-10-06 05:31
Location: /dev/chair
Has thanked: 78 times
Been thanked: 173 times

Re: Share your Debian SCRIPTS

#35 Post by steve_v »

Here's a little thing I've been using for a simple (and somewhat dumb, yes I know) remote backup of a couple of machines.
It's been ticking away as a daily cronjob for a couple of years now and it hasn't exploded on me yet, and as I've restored entire boxes from it's output without problems I figure it might be of some use to someone...
If nothing else, there's entertainment to be had from the gratuitous bashisms and abuse of arrays and regex expansion. :P

Code: Select all

#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Recursively sync a directory $src on a remote host to local directory $dest/$rhost and create a matching timestamp file. Intended for use by cron, outputs to system logs.

###

rhost=''
ruser='root'
src='/.'
dest='/mnt/tank/Backups/'
exclude=( '*.pid' '*.sock' '/dev/*' '/proc/*' '/sys/*' '/tmp/*' '/run/*' '/mnt/*' '/media/*' '/lost+found' '.cache' 'thumbnails' '.thumbnails'  'swapfile' '/home/*/.local/share/Trash/*' '/home/*/Games/*' '*.sqlite-wal' '/var/cache/distfiles/*' '/var/tmp/portage/*' )
# Mask rsync exit codes we don't want mail about:
# 23 = Partial file transfer.
# 24 = File has vanished.
ret_mask=( '23' '24' )
timeout='2h'

###

if [ -z "$rhost" ]; then
    if [ $# -eq 1 ]; then 
        rhost="$1"
    else
        printf '%s\n' "Hostname or IP address must be passed as the first (and only) argument, or by editing the head of this script."
        exit 1
    fi
fi

# Fragile and annoying to test, but it's either that or real lockfiles... I'm lazy and this works for me.
if [ "$(pgrep -cf "${0##*/} ${1}")" -gt 1 ]; then
    printf '%s\n' "A job for this host is already running."
    exit 1
fi

{
    if ! [[ " $(hostname -a) localhost " =~ [[:space:]]${rhost}[[:space:]] ]]; then
        src="${ruser}@${rhost}:${src}"
        printf '%s\n' "Attempting to wake host..."
        # Populate /etc/ethers if you want wakeonlan to work
        wakeonlan "${rhost}"
        sleep 30
    fi

    printf '%s\n' "Starting rsync job..."
    timeout -v -s2 -k20 $timeout rsync -aAXHhq --numeric-ids --delete --delete-excluded "${exclude[@]/#/--exclude=}" "${src}" "${dest}/${rhost}/"
    ret=$?
    if [ "$ret" -eq "0" ] || [[ ${ret_mask[*]} =~ ${ret} ]]; then
        printf '%s\n' "Job  finished."
        touch "${dest}/${rhost}.stamp"
        ret=0
    fi
} > >(logger -t "${0##*/} (${rhost})") 2>&1

if [ "$ret" -eq "0" ]; then
    exit 0
else
    printf '%s\n' "Rsync job for ${rhost} on $(date '+%b %d %X') failed (rsync exit code: ${ret}), please inspect system logs." 1>&2
    exit "${ret}"
fi
Note that this has no input sanitisation, and can be picky about how it is called. It works for me, but may eat your cat.
Once is happenstance. Twice is coincidence. Three times is enemy action. Four times is Official GNOME Policy.

User avatar
FreewheelinFrank
Global Moderator
Global Moderator
Posts: 2062
Joined: 2010-06-07 16:59
Has thanked: 38 times
Been thanked: 221 times

Re: Share your Debian SCRIPTS

#36 Post by FreewheelinFrank »

Here is a little script using Aptitude to notify of available updates in XFCE using the Genmon panel plugin. (Requires aptitude of course and also apt-config-auto-update to make Apt update its cache every day.)

update-notification.sh

Code: Select all

#!/bin/bash
updates=$(aptitude search '~U' | wc -l)
details=$(aptitude -F%p search '~U')

PANEL="<icon>software-update-available</icon>"
PANEL+="<iconclick>./update-script.sh</iconclick>"
PANEL+="<txt><span size='6000' rise='8000'>$updates</span></txt>"

TOOLTIP="<tool>"
TOOLTIP+="<span weight='bold'>Available updates: $updates</span>\n"
TOOLTIP+="$details\n"
TOOLTIP+="<span weight='bold'>Click icon to update</span>"
TOOLTIP+="</tool>"

if [ $updates -gt 0 ]; then
  echo -e "${PANEL}"
  echo -e "${TOOLTIP}"
else
  echo ""
fi
And here is the update script which must be in the same folder as the Genmon script.

update-script.sh

Code: Select all

#!/bin/bash
xterm -e "pkcon update && sleep 5s && xfce4-panel --plugin-event=genmon-2:refresh:bool:true"
Note: get the internal name of the Genmon plugin by hovering over the instance in Panel Preferences: in my panel I have two, so it's genmon-2.

Here is the Genmon command:

Code: Select all

/home/<user name>/update-notification.sh
Or wherever you keep the script. Has to be full path, I think.

No label, period 3600.

Here is the notification, tooltip and update process in action:

Image

Edited for clarity.
Last edited by FreewheelinFrank on 2022-12-04 17:43, edited 1 time in total.

User avatar
el_koraco
Posts: 242
Joined: 2011-10-20 11:49
Has thanked: 3 times
Been thanked: 8 times

Re: Share your Debian SCRIPTS

#37 Post by el_koraco »

FreewheelinFrank wrote: 2022-11-13 00:52 Image
Massive upvote for the *-*-fixed-misc-*-* font, best font ever.

User avatar
yesh
Posts: 23
Joined: 2021-07-22 03:04
Has thanked: 4 times
Been thanked: 2 times

Re: Share your Debian SCRIPTS

#38 Post by yesh »

FreewheelinFrank wrote: 2022-11-13 00:52 Here is a little script using Aptitude to notify of available updates in XFCE using the Genmon panel plugin. (Requires aptitude of course and also apt-config-auto-update to make Apt update its cache every day.)

Code: Select all

#!/bin/bash
updates=$(aptitude search '~U' | wc -l)
details=$(aptitude -F%p search '~U')

PANEL="<icon>software-update-available</icon>"
PANEL+="<iconclick>./update-script.sh</iconclick>"
PANEL+="<txt><span size='6000' rise='8000'>$updates</span></txt>"

TOOLTIP="<tool>"
TOOLTIP+="<span weight='bold'>Available updates: $updates</span>\n"
TOOLTIP+="$details\n"
TOOLTIP+="<span weight='bold'>Click icon to update</span>"
TOOLTIP+="</tool>"

if [ $updates -gt 0 ]; then
  echo -e "${PANEL}"
  echo -e "${TOOLTIP}"
else
  echo ""
fi
And here is the update script:

Code: Select all

#!/bin/bash
xterm -e "pkcon update && sleep 5s && xfce4-panel --plugin-event=genmon-2:refresh:bool:true"
Note: get the internal name of the Genmon plugin by hovering over the instance in Panel Preferences: in my panel I have two, so it's genmon-2.

Here is the Genmon command:

Code: Select all

/home/<user name>/update-notification.sh
Or wherever you keep the script. Has to be full path, I think.

No label, period 3600.

Here is the notification, tooltip and update process in action:

Image
I understand where to put the "Genmon command", and the "update script", but where does that first script go?
Image Stable Xfce / HP Notebook 15 BS143TU / Intel® Core™ i5-8250U / 8GB DDR4 2400Mhz / 1 TB SATA / Intel® UHD Graphics 620 (1366x768 15.6")

User avatar
FreewheelinFrank
Global Moderator
Global Moderator
Posts: 2062
Joined: 2010-06-07 16:59
Has thanked: 38 times
Been thanked: 221 times

Re: Share your Debian SCRIPTS

#39 Post by FreewheelinFrank »

yesh wrote: 2022-12-04 10:30
I understand where to put the "Genmon command", and the "update script", but where does that first script go?
Anywhere in your home directory, as long as you put the full path in Genmon. I put it in my user directory, but you could put it in a sub folder.

You have to have the second script in the same directory and it must be called update-script.sh, as it is called by that name in the first script.

Code: Select all

PANEL+="<iconclick>./update-script.sh</iconclick>"

User avatar
FreewheelinFrank
Global Moderator
Global Moderator
Posts: 2062
Joined: 2010-06-07 16:59
Has thanked: 38 times
Been thanked: 221 times

Re: Share your Debian SCRIPTS

#40 Post by FreewheelinFrank »

Action buttons in notifications.

I was wondering if I could have a desktop notification with notify-send for my XFCE Genmon script. My usual approach to scripting failed as the answer to the question at the usual scripting question sites seemed to be "It's not possible".

Image

However, the manual says it is possible.
OPTIONS

-A, --action=[NAME=]Text...
Specifies the actions to display to the user. Implies --wait to
wait for user input. May be set multiple times. The NAME of the
action is output to stdout. If NAME is not specified, the numerical
index of the option is used (starting with 1).
This action was added about a year ago.

https://gitlab.gnome.org/GNOME/libnotif ... equests/18

After a few attempts with the method from the cartoon, I managed to put together a working script. I'm posting it here so anybody searching for "Using notify-send, is there a way to associate a notification with some action?" can find a working example, not "It seems notify-send can't do this", or "No, notify-send doesn't support the use of actions/buttons", which isn't true any more.

Action buttons return a specified output (or an output of 0, 1... if no output text is specified). If they are not clicked, output is null. Thus

Code: Select all

--action=yes=Okay --action=no=Cancel
Returns "yes", "no" or null.

Code: Select all

--action=Okay --action=Cancel
Returns "0", "1" or null.

Output can be redirected to a text file:

Code: Select all

#!/bin/bash
notify-send --icon=system-software-update -w --action=yes="Click to update" "Updates available" > output.txt
action=$(cat output.txt)
if [ "$action" == "yes" ]; then
synaptic-pkexec
fi
or to a function:

Code: Select all

#!/bin/bash
action=$(notify-send --icon=system-software-update -w --action=yes="Click to update" "Updates available")
if [ "$action" == "yes" ]; then
synaptic-pkexec
fi
which seems like a better way to do it.

To have the number of updates appear in the notification:

Code: Select all

#!/bin/bash
updates=$(aptitude search '~U' | wc -l)
action=$(notify-send --icon=system-software-update -w --action=yes="Click to update" "$updates Updates available")
if [ "$action" == "yes" ]; then
synaptic-pkexec
fi
Image

Used in the Genmon script, you get a permanent reminder in the panel if an update is not done, and a reminder/record of the notification from the notification plugin.

Image

Post Reply