Useful scripts

This is a very nice section of the FreeBSD forums. Very creative,very useful. I want to give "my" contribute. Today I've created the script below with the precious help of C. It should fix a bhyve behavior that someone could dislikes,I think. Infact sometimes between the processes you can see some bhyve ghosted vms that aren't working anymore and should be killed,but to do that manually is boring and it takes some time. Maybe if you use one or two virtual machines at the same time only you haven't the problem that I'm talking about,but usually I start a lot of vms and I have some troubles.

Code:
#!/bin/sh


setxkbmap it

#set -eux

vms="$(ps ax | awk '/bhyve: [vm]/{print substr($6,1)}')"

vncs="$(ps ax | awk '/vncviewer [0]/{print $6}')"

for vm in $vms; do

                session="${vm##vm}"

                echo "bhyve session = $vms"

                echo "vnc session = $vncs"

                echo "$session"

                if ! printf '%s\n' "${vncs}" | grep "${session}"; then

                                printf 'VNC session not found,destroying ghost vms\n'

                                bhyvectl --vm=$vms --force-reset

                                bhyvectl --vm=$vms --destroy

                sleep 5

                else

                                printf 'Found VNC session %s\n' "${session},no ghost vms found,not destroying them"

                fi

done
 
Last edited:
last day of month
date -v -1d -j $(date -v +1m +%Y%m010000) +%d
or say you want to run a cron job in the last day of the month
Code:
#!/bin/sh
[ $(date -v +1d +%m) != $(date  +%m) ] || exit 0
# actual stuff here
 
I recently wrote a little Python script to display various CPU graphs (frequency, temperature, load) in a window on my X11 desktop.
It might be useful for others, too, so I put it on this web page. There are also screen shots.
The script may also serve as an example how to write simple X11 applications in Python. It also demonstrates how to retrieve and handle sysctl values in Python on FreeBSD.
Please read the instructions on the web page carefully. In particular, you have to install a few dependencies (Python3 for the script, Pillow for the image handling, Tkinter for the X11 widgets).
Here is a dark theme for your very nice script:
#Dark Theme
gc_width, gc_height = 360, 64 # size of one graph in pixels
gc_fg = "#505050" # default graph color
gc_bg = "#303030", "#404040" # graph background color(s) (alternating)
gc_sc = "black" # scale color
tooltip_bg = "#404040" #"#ffffa0"
gc_temp_range = 18.0, 50.0 # CPU temperature range to display (min, max)
 
This is a very nice section of the FreeBSD forums. Very creative,very useful. I want to give "my" contribute. Today I've created the script below with the precious help of C. It should fix a bhyve behavior that someone could dislikes,I think. Infact sometimes between the processes you can see some bhyve ghosted vms that aren't working anymore and should be killed,but to do that manually is boring and it takes some time. Maybe if you use one or two virtual machines at the same time only you haven't the problem that I'm talking about,but usually I start a lot of vms and I have some troubles.

Code:
#!/bin/sh


setxkbmap it

#set -eux

vms="$(ps ax | awk '/bhyve: [vm]/{print substr($6,1)}')"

vncs="$(ps ax | awk '/vncviewer [0]/{print $6}')"

for vm in $vms; do

                session="${vm##vm}"

                echo "bhyve session = $vms"

                echo "vnc session = $vncs"

                echo "$session"

                if ! printf '%s\n' "${vncs}" | grep "${session}"; then

                                printf 'VNC session not found,destroying ghost vms\n'

                                bhyvectl --vm=$vms --force-reset

                                bhyvectl --vm=$vms --destroy

                sleep 5

                else

                                printf 'Found VNC session %s\n' "${session},no ghost vms found,not destroying them"

                fi

done
I would optimize it this way:

Code:
-vms="$(ps ax | awk '/bhyve: [vm]/{print substr($6,1)}')"
-vncs="$(ps ax | awk '/vncviewer [0]/{print $6}')"
+PS_AX=$( ps ax )
+vms="$(echo "${PS_AX}" | awk '/bhyve: [vm]/{print substr($6,1)}')"
+vncs="$(echo "${PS_AX}" | awk '/vncviewer [0]/{print $6}')"

This way you do not waste time by running the same ps(1) command twice ... and you will have consistent/same results for both vms and vncs variables.
 
the $(command) construct will remove newlines so awk positional stuff wont work
Code:
PS=$(ps ax|tr '\n' '\1')
echo ${PS}|awk -v RS='\1'...
#this hack kind of works assuming ps output has no ^A in it
 
I'm working to improve that script,adding the attaching / detaching of the GPU I want (asking it at the beginning of the script) with the command devctl. It should be something like this :

Code:
#!/bin/sh

setxkbmap it
vms="$(ls /dev/vmm/*)"
vncs="vm$(ps ax | awk '/vncviewer [0]/{print $6}')"

echo "*** checkpoint 1"
echo "*** checkpoint 1"
echo "*** checkpoint 1"

printf 'Do you want to pass 1060 (a) or 2080ti (b) ?'
read answer
if [ "$answer" != "${answer#[a]}" ] ;then
    #echo "pci100:" ${pci100="pci0:1:0:0"}
    #echo "pci101:" ${pci101="pci0:1:0:1"}
    pci100="pci0:1:0:0"
    pci101="pci0:1:0:1"
    echo ${pci100}
    echo ${pci101}     
else
    #echo "pci200:" ${pci200="pci0:2:0:0"}
    #echo "pci201:" ${pci201="pci0:2:0:1"}
    #echo "pci202:" ${pci202="pci0:2:0:2"}
    #echo "pci203:" ${pci203="pci0:2:0:3"}
    pci200="pci0:2:0:0"
    pci201="pci0:2:0:1"
    pci202="pci0:2:0:2"
    pci203="pci0:2:0:3"
    echo ${pci200}
    echo ${pci201}
    echo ${pci202}
    echo ${pci203}          
fi
                
for vm in $vms; do
                session="${vm##*/}"   
                echo "bhyve session = $session"
                echo "vnc session = $vncs"

                if ! pciconf -l pci0:1:0:0 | grep -q "^ppt"; then
                echo "attach/detach driver ppt 1:0:0"
                devctl detach ${pci100}
                devctl set driver ${pci100} ppt
                /bin/sh
                fi

                if ! pciconf -l pci0:1:0:1 | grep -q "^ppt"; then
                echo "attach / detach driver ppt 1:0:1"
                devctl detach ${pci101}
                devctl set driver ${pci101} ppt
                fi
                
                if ! pciconf -l pci0:2:0:0 | grep -q "^ppt"; then
                echo "attach / detach driver ppt 2:0:0"
                devctl detach ${pci200}
                devctl set driver ${pci200} ppt
                fi

                if ! pciconf -l pci0:2:0:1 | grep -q "^ppt"; then
                echo "attach / detach driver ppt 2:0:1"
                devctl detach ${pci201}
                devctl set driver ${pci201} ppt
                fi

                if ! pciconf -l pci0:2:0:2 | grep -q "^ppt"; then
                echo "attach / detach driver ppt 2:0:2"
                devctl detach ${pci202}
                devctl set driver ${pci202} ppt
                fi

                if ! pciconf -l pci0:2:0:3 | grep -q "^ppt"; then
                echo "attach / detach driver ppt 2:0:3"
                devctl detach ${pci203}
                devctl set driver ${pci203} ppt
                fi

                if ! printf '%s\n' "${vncs}" | grep "${session}"; then
                                printf 'VNC session not found,destroying ghost vms\n'
                                bhyvectl --vm=$session --destroy
                echo "*** checkpoint 2"
                echo "*** checkpoint 2"
                echo "*** checkpoint 2"        
                                                                                 
                else
                                printf 'Found VNC session %s\n' "${session},no ghost vms found,not destroying them"
                echo "*** checkpoint 3"
                                echo "*** checkpoint 3"
                                echo "*** checkpoint 3"
                fi
done

echo "*** checkpoint 4"
echo "*** checkpoint 4"
echo "*** checkpoint 4"

vmdisk0=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (NM13N4CZ)/ && d{print d}'`
echo "Seagate M3 Portable 1.8 TB ; $vmdisk0"

vmdisk1=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (2015020204055E)/ && d{print d}'`
echo "TOSHIBA External USB 1.8 TB ; $vmdisk1"

vmdisk2=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (2022285F1175)/ && d{print d}'`
echo "CT1000P1SSD8 ; $vmdisk2"

vmdisk3=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (20130506005976F)/ && d{print d}'`
echo "TOSHIBA External USB 932GB ; echo $vmdisk3"

vmdisk4=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (BE0191500218)/ && d{print d}'`
echo "G-DISK ; $vmdisk4"

vmdisk5=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (38434B4237354B45)/ && d{print d}'`
echo "Elements ; $vmdisk5"

vmdisk6=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (WD-WCAV2X597309)/ && d{print d}'`
echo "WDC WD3200AAJS-00L7A0-298GB ; $vmdisk6"

vmdisk7=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (0774911DDC4200A6)/ && d{print d}'`
echo "SanDisk Cruzer-15GB ; $vmdisk7"

vmdisk8=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (60A44C4138D8F311190A0149)/ && d{print d}'`
echo "Kingston DataTraveler 2.0 ; $vmdisk8"

vmdisk9=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (20140100006C)/ && d{print d}'`
echo "SAMSUNG HM320JI ; $vmdisk9"

vmdisk10=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (1924E20B2AE5)/ && d{print d}'`
echo "CT500MX500SSD4 ; $vmdisk10"

mount -t ufs /dev/$vmdisk0'p2' /mnt/$vmdisk0'p2'

echo "*** checkpoint 5"
echo "*** checkpoint 5"
echo "*** checkpoint 5"
if [ "$answer" != "${answer#[a]}" ] ;then

bhyve -S -c sockets=2,cores=2,threads=2 -m 4G -w -H -A \
-s 0,hostbridge \
-s 1,virtio-blk,/mnt/$vmdisk0'p2'/bhyve/img/Linux/ubuntu2004-SD.img,bootindex=1 \
-s 2,virtio-blk,/dev/$vmdisk3 \
-s 8:0,passthru,$pci100 \
-s 8:1,passthru,$pci101 \
-s 11,virtio-net,tap20 \
-s 12,virtio-9p,sharename=/ \
-s 13,hda,play=/dev/dsp,rec=/dev/dsp \
-s 29,fbuf,tcp=0.0.0.0:5920,w=1600,h=950 \
-s 30,xhci,tablet \
-s 31,lpc \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_BHF_CODE.fd \
vm0:20 < /dev/null & sleep 2 && vncviewer 0:20
else
bhyve -S -c sockets=2,cores=2,threads=2 -m 4G -w -H -A \
-s 0,hostbridge \
-s 1,virtio-blk,/mnt/$vmdisk0'p2'/bhyve/img/Linux/ubuntu2004-SD.img,bootindex=1 \
-s 2,virtio-blk,/dev/$vmdisk3 \
-s 8:0,passthru,$pci200 \
-s 8:1,passthru,$pci201 \
-s 8:2,passthru,$pci202 \
-s 8:3,passthru,$pci203 \
-s 11,virtio-net,tap20 \
-s 12,virtio-9p,sharename=/ \
-s 13,hda,play=/dev/dsp,rec=/dev/dsp \
-s 29,fbuf,tcp=0.0.0.0:5920,w=1600,h=950 \
-s 30,xhci,tablet \
-s 31,lpc \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_BHF_CODE.fd \
vm0:20 < /dev/null & sleep 2 && vncviewer 0:20
fi
echo "*** checkpoint 6"
echo "*** checkpoint 6"
echo "*** checkpoint 6"

it does not work out of the box. I'm not experienced,even if I want to learn. That most important thing is to not complicate the script too much. Remember that what for you is easy to understand,for a newbie it is not.
 
I'm working to improve that script,adding the attaching / detaching of the GPU I want (asking it at the beginning of the script) with the command devctl. It should be something like this :

Code:
#!/bin/sh

setxkbmap it
vms="$(ls /dev/vmm/*)"
vncs="vm$(ps ax | awk '/vncviewer [0]/{print $6}')"
echo $vms
echo $vncs

if ! pciconf -l pci0:2:0:0 | grep -q "^ppt"; then
echo "rtx 2080ti slot 2/0/0 is not attached to ppt,attaching..."
kldload nvidia-modeset
devctl detach pci0:2:0:0
devctl set driver pci0:2:0:0 ppt
else
echo "rtx 2080ti slot 2/0/0 is already attached to ppt"
fi

if ! pciconf -l pci0:2:0:1 | grep -q "^ppt"; then
echo "rtx 2080ti slot 2/0/1 is not attached to ppt,attaching..."
devctl detach pci0:2:0:1
devctl set driver pci0:2:0:1 ppt
else
echo "rtx 2080ti slot 2/0/1 is already attached to ppt"
fi

if ! pciconf -l pci0:2:0:2 | grep -q "^ppt"; then
echo "rtx 2080ti slot 2/0/2 is not attached to ppt,attaching..."
devctl detach pci0:2:0:2
devctl set driver pci0:2:0:2 ppt
else
echo "rtx 2080ti slot 2/0/2 is already attached to ppt"
fi

if ! pciconf -l pci0:2:0:3 | grep -q "^ppt"; then
echo "rtx 2080ti slot 2/0/3 is not attached to ppt,attaching..."
#devctl detach pci0:2:0:3
devctl set driver pci0:2:0:3 ppt
else
echo "rtx 2080ti slot 2/0/3 is already attached to ppt"
fi

echo "rtx 2080ti is fully attached to ppt"

#devctl detach pci0:5:0:0
#devctl set driver pci0:5:0:0 ppt

for vm in $vms; do
                session="${vm##*/}" 
                echo "bhyve session = $session"
                echo "vnc session = $vncs"
                                if ! printf '%s\n' "${vncs}" | grep "${session#vm}"; then
                                printf 'VNC session not found,destroying ghost vms\n'
                                bhyvectl --vm=$session --destroy
                                ls /dev/vmm/                                                                                                            
                else
                                printf 'Found VNC session %s\n' "${session},no ghost vms found,not destroying them"
                ls /dev/vmm/
                                fi
done

vmdisk0=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (NM13N4CZ)/ && d{print d}'`
echo "Seagate M3 Portable 1.8 TB ; $vmdisk0"

vmdisk1=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (2015020204055E)/ && d{print d}'`
echo "TOSHIBA External USB 1.8 TB ; $vmdisk1"

vmdisk2=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (2022285F1175)/ && d{print d}'`
echo "CT1000P1SSD8 ; $vmdisk2"

vmdisk3=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (20130506005976F)/ && d{print d}'`
echo "TOSHIBA External USB 932GB ; echo $vmdisk3"

vmdisk4=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (BE0191500218)/ && d{print d}'`
echo "G-DISK ; $vmdisk4"

vmdisk5=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (38434B4237354B45)/ && d{print d}'`
echo "Elements ; $vmdisk5"

vmdisk6=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (WD-WCAV2X597309)/ && d{print d}'`
echo "WDC WD3200AAJS-00L7A0-298GB ; $vmdisk6"

vmdisk7=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (0774911DDC4200A6)/ && d{print d}'`
echo "SanDisk Cruzer-15GB ; $vmdisk7"

vmdisk8=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (60A44C4138D8F311190A0149)/ && d{print d}'`
echo "Kingston DataTraveler 2.0 ; $vmdisk8"

vmdisk9=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (20140100006C)/ && d{print d}'`
echo "SAMSUNG HM320JI ; $vmdisk9"

vmdisk10=`geom disk list | awk '/^Geom name: /{d=$NF} /^ *ident: (1924E20B2AE5)/ && d{print d}'`
echo "CT500MX500SSD4 ; $vmdisk10"

pkexec zpool import -f -R /mnt/zroot2 zroot2

bhyve -S -c sockets=2,cores=2,threads=2 -m 4G -w -H -A \
-s 0,hostbridge \
-s 1,virtio-blk,/mnt/zroot2/zroot2/bhyve/img/Linux/ubuntu2004.img,bootindex=1 \
-s 8:0,passthru,2/0/0 \
-s 8:1,passthru,2/0/1 \
-s 8:2,passthru,2/0/2 \
-s 8:3,passthru,2/0/3 \
-s 9,passthru,5/0/0 \
-s 11,virtio-net,tap13 \
-s 12,virtio-9p,sharename=/ \
-s 13,hda,play=/dev/dsp,rec=/dev/dsp \
-s 29,fbuf,tcp=0.0.0.0:5913,w=1600,h=950 \
-s 30,xhci,tablet \
-s 31,lpc \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_BHF_CODE.fd \
vm0:13 < /dev/null & sleep 2 && vncviewer 0:13
 
Last edited:
I can highly recommend using a nullfs mount to share a socket towards a jail. I'm using this for X11 socket sharing for example; this saves you from having to move anything.

True. Another option is to ln (not -s) the socket into a Jail.

The difficulty is that the linked socket must be on the same filesystem, whereas with a nullfs mount, you could mount to /tmp/.X11-unix *and* i.e /jails/somejail/tmp/.X11-unix?
 
Not very useful, maybe fun....
shell made ip tunnel
replace xxx.yyy.com with your server's script ip/fqdn
Code:
#!/bin/sh
#server
PORT=29999
echo Running as server on $(hostname) $PORT
ifconfig tun0 destroy
ifconfig tun0 create 55.66.77.89 55.66.77.88
nc -l $PORT  0<>/dev/tun0 >&0

===============================================

#!/bin/sh
# client
echo "Running as client"
ifconfig tun0 destroy
ifconfig tun0 create 55.66.77.88 55.66.77.89
nc xxx.yyy.com 29999 0<>/dev/tun0 >&0


================================================

[titus@hp430 ~]$ ping 55.66.77.89
PING 55.66.77.89 (55.66.77.89): 56 data bytes
64 bytes from 55.66.77.89: icmp_seq=0 ttl=64 time=35.397 ms
64 bytes from 55.66.77.89: icmp_seq=1 ttl=64 time=35.333 ms
64 bytes from 55.66.77.89: icmp_seq=2 ttl=64 time=35.308 ms
^C
--- 55.66.77.89 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 35.308/35.346/35.397/0.037 ms
[titus@hp430 ~]$ route -n get  55.66.77.89
   route to: 55.66.77.89
destination: 55.66.77.89
        fib: 0
  interface: tun0
      flags: <UP,HOST,DONE,PINNED>
 recvpipe  sendpipe  ssthresh  rtt,msec    mtu        weight    expire
       0         0         0         0      1500         1         0
[titus@hp430 ~]$
 
the $(command) construct will remove newlines so awk positional stuff wont work
Code:
PS=$(ps ax|tr '\n' '\1')
echo ${PS}|awk -v RS='\1'...
#this hack kind of works assuming ps output has no ^A in it

something like this is good ? (I tried to mix together your suggestion with the suggestion of vermaden)

Code:
PS=$(ps ax|tr '\n' '\1')
echo ${PS}|awk -v RS='\1'
vms="$(echo "${PS_AX}" | awk '/bhyve: [vm]/{print substr($6,1)}')"
vncs="$(echo "${PS_AX}" | awk '/vncviewer [0]/{print $6}')"
 
works form me
Code:
 $cat zio.sh
PS_AX=$(ps ax|tr '\n' '\1')
vms="$(echo "${PS_AX}" | awk -v RS='\1' '/bhyve: /{print substr($6,1)}')"
#vncs="$(echo "${PS_AX}" | awk -v RS='\1' '/vncviewer [0]/{print $6}')"
echo $vms
#echo $vncs
 $sh zio.sh
winguest netbsd ubuntu
 
works form me
Code:
 $cat zio.sh
PS_AX=$(ps ax|tr '\n' '\1')
vms="$(echo "${PS_AX}" | awk -v RS='\1' '/bhyve: /{print substr($6,1)}')"
#vncs="$(echo "${PS_AX}" | awk -v RS='\1' '/vncviewer [0]/{print $6}')"
echo $vms
#echo $vncs
 $sh zio.sh
winguest netbsd ubuntu

why did you comment this ?

Code:
#vncs="$(echo "${PS_AX}" | awk -v RS='\1' '/vncviewer [0]/{print $6}')"

I need this statement.
 
Hi,

Three little scripts that allow you to get the ten last information about Freebsd from the terminal: "security advisories", "errata notices" and "news".
It's an alternative to mailing lists and web pages, shell being quicker I like it, but in case more details are needed the web browser is still there.
Hope you'll enjoy them as I do.

Bash:
#!/usr/bin/env sh
# NAME: fbsd_advisory
# DESCRIPTION: print the last ten security advisories
# DEPENDENCIES: htmlq

# set -x
set -eu

url="https://www.freebsd.org/security/advisories/"
ftemp=$(mktemp)

fetch --quiet --retry -4 "$url" --output "$ftemp"

ftext=$(htmlq --filename "$ftemp" --text "#contentwrap" --ignore-whitespace \
        | sed "/^$/d" \
        | sed "1,11d" \
        | head --lines 20)

h1="DATE"
h2="ADVISORY"
l1="----------"
l2="--------------------"

dt=$(echo "$ftext" | grep -E "^[0-9]{4}[-/][0-9]{2}[-/][0-9]{2}")
nm=$(echo "$ftext" | grep -E "FreeBSD-SA")
tb=$(printf "%s\n" "$h1" "$l1" "$dt" "$h2" "$l2" "$nm" \
    | pr -2 -s -t \
    | column -t)

echo "$tb"
rm -f "$ftemp"
adv.png



Bash:
#!/usr/bin/env sh
# NAME: fbsd_errata
# DESCRIPTION: print the ten last errata notices
# DEPENDENCIES: htmlq

# set -x
set -eu

url="https://www.freebsd.org/security/notices/"
ftemp=$(mktemp)

fetch --quiet --retry -4 "$url" --output "$ftemp"

ftext=$(htmlq --filename "$ftemp" --text "#contentwrap" --ignore-whitespace \
        | sed "/^$/d" \
        | sed "1,5d" \
        | head --lines 20)

h1="DATE"
h2="ERRATA_NOTICES"
l1="----------"
l2="-----------------------"
dt=$(echo "$ftext" | grep -E "^[0-9]{4}[-/][0-9]{2}[-/][0-9]{2}")
nm=$(echo "$ftext" | grep -E "FreeBSD-EN")
tb=$(printf "%s\n" "$h1" "$l1" "$dt" "$h2" "$l2" "$nm" \
    | pr -2 -s -t \
    | column -t)

echo "$tb"
rm -f "$ftemp"

err.png


Bash:
#!/usr/bin/env sh
# NAME: fbsd_news
# DESCRIPTION: print the last ten Freebsd news
# DEPENDENCIES: htmlq

# set -x
set -eu   

url="https://www.freebsd.org/news/newsflash/"
ftemp1=$(mktemp)
ftemp2=$(mktemp)

fetch --quiet --retry -4 "$url" --output "$ftemp1"

htmlq --filename "$ftemp1" --text ".localized" --ignore-whitespace \
        | tr -s '[:space:]' ' ' \
        | sed -E "s/[0-9]{1,2}[ ]{1}[A-Z]{1}[a-z]*:/\n&/g" \
        | sed "/^$/d" \
        | sed "s/:/ ..../" \
        | head --lines 10 > "$ftemp2"

sed -i '' -e '1 i\
---------       --------------------
' "$ftemp2"

sed -i '' -e '1 i\
DATE            NEWS
' "$ftemp2"

cat "$ftemp2"
rm -f "$ftemp1" "$ftemp2"

new.png


PS:
Thanks to the two guys who helped me to "think differently" :)
 
"When you write a script but you fail to remember how you've done it before!" this is exactly the reason why I made this one.
Sometimes human memory isn't reliable enough (at least in my case), if I remember only partially a command I already used but I don't want to check scripts one by one to find the snippet that did the trick, well I have a tool for this.

So the script searches for a pattern in a directory where your scripts are. To work it needs an argument e.g "grep -v", or just awk without quote.
Then it shows all the scripts where the argument is found, finally the selected file via fuzzy tool(I love this amazing tool) is opened in an editor.
Nothing extradordinary I know but if it's useful for me it can also help someone else I guess.

Bash:
#!/usr/bin/env sh
# NAME: sepat (se)arch (pat)tern
# DESCRIPTION: search pattern through already written scripts
# DEPENDENCIES: fzy

# set -x
set -eu

usage() {
echo "Usage: $0 pattern"
exit 1 
}

if [ $# -ne 1 ];
then usage
fi

dirscript="$HOME"/bin/

if ! find "$dirscript" -type f -perm -u+x -depth 1 -print0 \
    | xargs -0 grep -n "$1" > /dev/null
then echo "No match found." && exit
fi

linescript=$(find "$dirscript" -type f -perm -u+x -depth 1 -print0 \
            | xargs -0 grep -n "$1" \
            | fzy --prompt="pattern: ")

namescript=$(echo "$linescript" | sed "s/:.*$//g")

EDITOR=${EDITOR:=ee}
$EDITOR "$namescript" || exit

fetch.png


curl.png

getopt.png
 

Attachments

  • getopt.png
    getopt.png
    8.8 KB · Views: 76
Here's a short shell script to calculate the number of days between two dates:
Code:
#! /bin/sh

#
#  return days between two dates
#

#
# dates in the form mo/dy/year
#

help()
{
    echo "$0 -1 first-date -2 second-date"
    echo "order doesn't matter"
    exit
}

D1=""
D2=""

while getopts :1:2: a
do
    case $a in
    1) D1=$OPTARG;;
    2) D2=$OPTARG;;
    *) help;;
    esac
done

if [ "$D1" = "" -o "$D2" = "" ]
then
    help
fi

t1=$(date -jf "%m/%d/%Y" "$D1" +%s)
t2=$(date -jf "%m/%d/%Y" "$D2" +%s)
if [ "$t2" -gt "$t1" ]
then
    D3=$(( ($t2 - $t1) / 86400 ))
else
    D3=$(( ($t1 - $t2) / 86400 ))
fi

echo $D3

You don't need to worry about which date to enter first, the script orders them itself. It probably wasn't really necessary to use the -1 and -2 format for this, but it doesn't hurt anything.
 
Here's a simple script to calculate the length of a drill point given the included angle and diameter. A nice wrinkle is that the diameter can be entered as a decimal value or as a fraction: 0.375 or 3/8).
Code:
#! /bin/sh


help() 
{
    printf "`basename $0`: calculate drill point length\n"
    printf "  -d #: drill diameter\n"
    printf "  -a #: included point angle\n"
    exit
}

A=0
D=0

while getopts :a:d: a
do
    case $a in
      a) A=$OPTARG;;
      d) D=$OPTARG;;
      *) help;;
    esac
done

if [ $A = 0 -o $D = 0 ]
then
    help
fi

if [ ! ${D##*/*} ]
then
    D=`echo "f=$D+0.0005;scale=3;print f/1"|bc -l`
fi

bc -l <<-EOF
    # radius from diameter
    r=$D/2
    # adjust angle to (90 - angle/2)
    i=90-$A/2
    # convert to radians
    i=i*a(1)/45
    # calculate point length
    l=r*s(i)/c(i)
    l+=0.0005
    scale=3
    print "Point length = ", l/1, "\n"
EOF
 
This cleans out duplicate lines of an inputted text file while retaining the first occurrence order.
I use this often to help me clean out duplicate command entries in a shell history file.
Python:
#!/usr/bin/env python3

import sys
from pathlib import Path


if __name__ == "__main__":
    path = Path(sys.argv[1])
    with path.open() as f:
        lines = list({
            f"{line.rstrip()}\n": None
            for line in f.readlines()
        })
    path.write_text("".join(lines))
 
Code:
#!/usr/local/bin/bash

# 0-----------------------------------------------0
# | scan_local_storage                            |
# | list mountable permantent-storage filesystems |
# | - tries to r/o mount ufs, msdosfs and ntfs    |
# | - requires fusefs kmod loaded                 |
# | - requires package fusefs-ntfs + deps         |
# | - tested on 13.2                              |
# 0-----------------------------------------------0

device_types="ada nvd da"
mtpt="/tmp/mnt_test"
mkdir -p $mtpt
IFS=''

echo "device  partition fstype    mountable"
echo "-------------------------------------"
echo $device_types | tr ' ' '\n' | while read storage_type
do
  ls /dev/${storage_type}? 2>/dev/null | while read storage_dev
  do
    storage_dev="$(basename $storage_dev)"
    (
      ls /dev/${storage_dev}p? 2>/dev/null
      ls /dev/${storage_dev}s?? 2>/dev/null
    ) | while read part
    do
      part="$(basename $part)"
      filesystem="$(fstyp /dev/$part 2>/dev/null)"
      if [ -n "$filesystem" ]
      then
        prev_dev=$dev
        [ "$prev_dev" != "$storage_dev" ] && [ "$prev_dev" != " " ] && dev=$storage_dev || dev=" "
        printf "%-8s%-10s%-10s" $dev $part $filesystem
        case $filesystem in
          "ufs")
            mount -r /dev/$part $mtpt > /dev/null 2>&1
            if [ $? = 0 ]
            then
              echo "yes"
              umount $mtpt
            else
              echo "no"
            fi
          ;;
          "msdosfs")
            mount -r -t msdosfs /dev/$part $mtpt > /dev/null 2>&1
            if [ $? = 0 ]
            then
              echo "yes"
              umount $mtpt
            else
              echo "no"
            fi
          ;;
          "ntfs")
            ntfs-3g -o ro /dev/$part $mtpt > /dev/null 2>&1
            if [ $? = 0 ]
            then
              echo "yes"
              umount $mtpt
            else
              echo "no"
            fi
          ;;
          *)
            echo
          ;;
        esac
      fi
    done
  done
done

rmdir $mtpt
 
Github can create distfiles "on the fly", e.g. from tags, which is a pretty nice feature. But, those distfiles don't include any git submodules.

As I'm using one submodule in most of my projects (my own generic GNU-make "framework"), I finally decided to create distfiles myself.

It's super easy with some scripting :cool:

Bash:
#/bin/sh

GH_ACCOUNT=Zirias
VERSIONTAGPREFIX=v

if [ ! \( $# = 2 -o $# = 3 \) ]; then
        echo >&2 Usage: $0 package version [commit]
        exit 1
fi

PKGNAME=$1
PKGVER=$2
PKGCOMMIT=$3

TAGARG=
[ -z "${PKGCOMMIT}" ] && TAGARG="-b ${VERSIONTAGPREFIX}${PKGVER}"
DISTNAME=${PKGNAME}-${PKGVER}

if ! git clone https://github.com/${GH_ACCOUNT}/${PKGNAME}.git \
        ${TAGARG} --recurse-submodules ${DISTNAME}; then
        rm -fr ${DISTNAME}
        echo >&2 Error cloning ${DISTNAME}
        exit 1
fi

[ -n "${PKGCOMMIT}" ] && if ! ( cd ${DISTNAME} && \
        git checkout --recurse-submodules ${PKGCOMMIT} ); then
        rm -fr ${DISTNAME}
        echo >&2 Error checking out ${PKGCOMMIT}
        exit 1
fi

tar --exclude-vcs -cJf ${DISTNAME}.tar.xz ${DISTNAME}
rm -fr ${DISTNAME}

To create a release tarball, e.g. makedist.sh poser 1.0 will create poser-1.0.tar.xz.

To create a pre-release snapshot, e.g. makedist.sh poser 1.0.0.20230601 3088b7c creates poser-1.0.0.20230601.tar.xz from the commit hash given.
 
Upgraded my "find path of self" method for (executable) shell scripts:

Code:
prefix="$(cd "$(dirname "$(realpath "$(which "$0")")")" && pwd)"

Description, from inner to outer:

$0 - The script name (i.e '/opt/blender24/run_blender', 'run_blender' or '../run_blender'
which - Obtain a full path to the script if run from $PATH (i.e 'run_blender')
realpath - Obtain a full path to the script if it is a symbolic link (i.e '/usr/local/bin/current_blender')
dirname - Find the containing directory (i.e '/opt/blender24')
cd && pwd - Use temp shell to cd into directory and output current directory name (solves relative paths)

Pretty hacky but more portable than /proc and many other solutions seem to lack one or more of these edge cases described above.

You can perhaps skip the realpath part because people shouldn't really be treating symlinks like Microsoft Windows shortcuts. For *non-executable* shell scripts (i.e 'run_blender.sh'), they shouldn't be in path, so you can also ignore the which part.
 
A script to generate a "version" of x11/xorg which resides in /usr/X11R7 (like $DEITY intended).

I used to simply rebuild it *all* from ports but I found another way that is faster and sidesteps compile errors.

Notice in the below screenshot that my pkg info list looks tidy and manageable rather than being spammed with xorg cruft. This takes the more OpenBSD approach of Xorg being part of the base install (which I feel to be the better choice).

x11r7_freebsd.png


Code:
#!/bin/sh

set -e

arch=amd64
release=13.2-RELEASE

selected_packages=" \
  mesa-dri \
  xorg-apps \
  xorg-docs \
  xorg-drivers \
  xorg-fonts \
  xorg-libraries \
  glx-utils \
  open-motif \
  xfontsel"

dest_prefix=/usr/X11R7

currdir="$(pwd)"

prep()
{
  mkdir work
  cd work
}

do_fetch()
{
  echo "[Fetching chroot base]"
  fetch "https://download.freebsd.org/releases/${arch}/${release}/base.txz"

  echo "[Extracting chroot base]"
  mkdir prefix
  tar -C prefix -xf base.txz
}

conf_prefix()
{
  echo "[Configuring chroot]"
  mount -t devfs devfs prefix/dev
  cp /etc/resolv.conf prefix/etc
}

prefix_packages()
{
  echo "[Fetching packages]"
  chroot prefix pkg bootstrap --yes
  chroot prefix pkg install --yes ${selected_packages}
  chroot prefix pkg remove --yes -f pkg
}

copy_prefix()
{
  echo "[Copying package prefix]"
  cp -R prefix/usr/local "${dest_prefix}"
}

do_patch()
{
  echo "[Patching paths]"
  local files="$(find "${dest_prefix}")"

  for file in ${files}; do
    if [ -f "${file}" ]; then
      set +e
      sed -i "" "s#/usr/local#${dest_prefix}#g" "${file}" 2>/dev/null
      set -e
    fi
  done
}

do_local()
{
  echo "[Updating LD]"
  echo "${dest_prefix}/lib" > /etc/ld-elf.so.conf
  ldconfig -m /etc/ld-elf.so.conf

  echo "[Reinstating setuid]"
  chmod u+s "${dest_prefix}/libexec/Xorg.wrap"
}

create_archive()
{
  cd "${currdir}"

  echo "[Archiving X11R7]"
  tar -czf xbase.tar.gz "${dest_prefix}"
}

cleanup()
{
  cd "${currdir}"

  echo "[Cleaning up]"
  umount work/prefix/dev
  chflags -R noschg work/prefix
  rm -r -f work
}

prep
do_fetch
conf_prefix
prefix_packages
copy_prefix
do_patch
do_local
create_archive
cleanup
 
Back
Top