home.social

#unixshell — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #unixshell, aggregated by home.social.

  1. Highest system load I've seen (while the system was still responsive, that is):

    Thu Apr 16 05:02:25 PM CDT 2026 83.95 (6.995 per processor (12))
    

    Was batch converting ~250 jpegs into avif, running 16 processes concurrently.
    #UnixShell makes it stupidly easy. :D

    (hint: ncpus=$(lscpu -bp |grep -c "^[0-9]"); while (( $(jobs) >= ncpus )); do sleep 1; done ;)

  2. Something that I'd love to be able to do, but haven't figured out how, yet:

    You can run somecommand 2>&1 > log.txt to get STDOUT and STDERR together, but you won't know which is which.
    You can run somecommand 2>err.txt >log.txt to get STDOUT and STDERR separate, but you won't know the timing, or which error messages happened between which STDOUT messages.
    I'd like to figure out some way to combine both, so you end up with a file like this:

    1: this was a STDOUT message
    1: this was a STDOUT message
    1: this was a STDOUT message
    2: this was a STDERR message
    2: this was a STDERR message
    1: this was a STDOUT message
    2: this was a STDERR message
    1: this was a STDOUT message
    1: this was a STDOUT message
    1: this was a STDOUT message
    1: this was a STDOUT message
    1: this was a STDOUT message
    2: this was a STDERR message
    2: this was a STDERR message
    

    Any ideas? @mirabilos?

    #Unix #UnixShell #Linux #BSD

  3. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  4. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  5. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  6. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  7. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  8. I'm not saying you should all go out and set up aliases to enable your various typos and slip-ups, but I honestly don't know why I didn't do this 25 years ago.

    alias cd..='cd ..'
    

    #bash #UNIX #Shell #UnixShell #POSIX

  9. Recursion usually scares me a bit, but it worked out nicely here:

    #convert "cx"-style Esperanto notation to native accents (ĉ)
    function eaccent {
        if [[ ${1:-} ]]; then
            echo "$*" |eaccent
        else
            sed 's/cx/ĉ/g; s/gx/ĝ/g; s/hx/ĥ/g; s/jx/ĵ/g; s/sx/ŝ/g; s/ux/ŭ/g; s/C[xX]/Ĉ/g; s/G[xX]/Ĝ/g; s/H[xX]/Ĥ/g; s/J[xX]/Ĵ/g; s/S[xX]/Ŝ/g; s/U[xX]/Ŭ/g'
        fi
    }
    

    #bash #unix #shell #scripts #scripting #UnixShell #ShellScripting #Esperanto

  10. Recursion usually scares me a bit, but it worked out nicely here:

    #convert "cx"-style Esperanto notation to native accents (ĉ)
    function eaccent {
        if [[ ${1:-} ]]; then
            echo "$*" |eaccent
        else
            sed 's/cx/ĉ/g; s/gx/ĝ/g; s/hx/ĥ/g; s/jx/ĵ/g; s/sx/ŝ/g; s/ux/ŭ/g; s/C[xX]/Ĉ/g; s/G[xX]/Ĝ/g; s/H[xX]/Ĥ/g; s/J[xX]/Ĵ/g; s/S[xX]/Ŝ/g; s/U[xX]/Ŭ/g'
        fi
    }
    

    #bash #unix #shell #scripts #scripting #UnixShell #ShellScripting #Esperanto

  11. Recursion usually scares me a bit, but it worked out nicely here:

    #convert "cx"-style Esperanto notation to native accents (ĉ)
    function eaccent {
        if [[ ${1:-} ]]; then
            echo "$*" |eaccent
        else
            sed 's/cx/ĉ/g; s/gx/ĝ/g; s/hx/ĥ/g; s/jx/ĵ/g; s/sx/ŝ/g; s/ux/ŭ/g; s/C[xX]/Ĉ/g; s/G[xX]/Ĝ/g; s/H[xX]/Ĥ/g; s/J[xX]/Ĵ/g; s/S[xX]/Ŝ/g; s/U[xX]/Ŭ/g'
        fi
    }
    

    #bash #unix #shell #scripts #scripting #UnixShell #ShellScripting #Esperanto

  12. Recursion usually scares me a bit, but it worked out nicely here:

    #convert "cx"-style Esperanto notation to native accents (ĉ)
    function eaccent {
        if [[ ${1:-} ]]; then
            echo "$*" |eaccent
        else
            sed 's/cx/ĉ/g; s/gx/ĝ/g; s/hx/ĥ/g; s/jx/ĵ/g; s/sx/ŝ/g; s/ux/ŭ/g; s/C[xX]/Ĉ/g; s/G[xX]/Ĝ/g; s/H[xX]/Ĥ/g; s/J[xX]/Ĵ/g; s/S[xX]/Ŝ/g; s/U[xX]/Ŭ/g'
        fi
    }
    

    #bash #unix #shell #scripts #scripting #UnixShell #ShellScripting #Esperanto

  13. Recursion usually scares me a bit, but it worked out nicely here:

    #convert "cx"-style Esperanto notation to native accents (ĉ)
    function eaccent {
        if [[ ${1:-} ]]; then
            echo "$*" |eaccent
        else
            sed 's/cx/ĉ/g; s/gx/ĝ/g; s/hx/ĥ/g; s/jx/ĵ/g; s/sx/ŝ/g; s/ux/ŭ/g; s/C[xX]/Ĉ/g; s/G[xX]/Ĝ/g; s/H[xX]/Ĥ/g; s/J[xX]/Ĵ/g; s/S[xX]/Ŝ/g; s/U[xX]/Ŭ/g'
        fi
    }
    

    #bash #unix #shell #scripts #scripting #UnixShell #ShellScripting #Esperanto

  14. Quick tip if you ever need to add a linebreak to the end of a file manually for whatever reason, `echo >> filename` works.

    #Linux #Shell #UnixShell #LinuxShell #Bash

  15. When you're dealing with plaintext data in a suspicious context, consider using `cat -v` where you'd usually use `cat`.

    ```
    -v, --show-nonprinting
    use ^ and M- notation, except for LFD and TAB
    ```

  16. File this under #shell #functions I should have written years ago:

    function grepc {
        #Do a grep -c, but skipping files with no results
        grep -c "$@" |grep -v ':0$'
    }
    

    #unix #UnixShell #ShellScripting #bash #ksh

  17. P.S., the body of the parent #toot was created by a simple #shell #function:

    function apod {
        #Today's NASA Astronomy Picture of the Day info-fetcher
        curl -sL 'https://apod.nasa.gov/apod/archivepix.html' \
            |grep -m1 "[0-9][0-9]:" \
            |sed 's/^/Date: /;
                s|: *<a href="|\nURL: https://apod.nasa.gov/apod/|;
                s/">/\nTitle: /; s/<.*$//'
        echo
        echo "#NASA #Astronomy #PictureOfTheDay"
    }
    

    #bash #ksh #mksh #shellScripting #unix #UnixShell #WebScraping #Scraping #HTML

  18. P.S., the body of the parent #toot was created by a simple #shell #function:

    function apod {
        #Today's NASA Astronomy Picture of the Day info-fetcher
        curl -sL 'https://apod.nasa.gov/apod/archivepix.html' \
            |grep -m1 "[0-9][0-9]:" \
            |sed 's/^/Date: /;
                s|: *<a href="|\nURL: https://apod.nasa.gov/apod/|;
                s/">/\nTitle: /; s/<.*$//'
        echo
        echo "#NASA #Astronomy #PictureOfTheDay"
    }
    

    #bash #ksh #mksh #shellScripting #unix #UnixShell #WebScraping #Scraping #HTML

  19. P.S., the body of the parent #toot was created by a simple #shell #function:

    function apod {
        #Today's NASA Astronomy Picture of the Day info-fetcher
        curl -sL 'https://apod.nasa.gov/apod/archivepix.html' \
            |grep -m1 "[0-9][0-9]:" \
            |sed 's/^/Date: /;
                s|: *<a href="|\nURL: https://apod.nasa.gov/apod/|;
                s/">/\nTitle: /; s/<.*$//'
        echo
        echo "#NASA #Astronomy #PictureOfTheDay"
    }
    

    #bash #ksh #mksh #shellScripting #unix #UnixShell #WebScraping #Scraping #HTML

  20. P.S., the body of the parent #toot was created by a simple #shell #function:

    function apod {
        #Today's NASA Astronomy Picture of the Day info-fetcher
        curl -sL 'https://apod.nasa.gov/apod/archivepix.html' \
            |grep -m1 "[0-9][0-9]:" \
            |sed 's/^/Date: /;
                s|: *<a href="|\nURL: https://apod.nasa.gov/apod/|;
                s/">/\nTitle: /; s/<.*$//'
        echo
        echo "#NASA #Astronomy #PictureOfTheDay"
    }
    

    #bash #ksh #mksh #shellScripting #unix #UnixShell #WebScraping #Scraping #HTML

  21. P.S., the body of the parent #toot was created by a simple #shell #function:

    function apod {
        #Today's NASA Astronomy Picture of the Day info-fetcher
        curl -sL 'https://apod.nasa.gov/apod/archivepix.html' \
            |grep -m1 "[0-9][0-9]:" \
            |sed 's/^/Date: /;
                s|: *<a href="|\nURL: https://apod.nasa.gov/apod/|;
                s/">/\nTitle: /; s/<.*$//'
        echo
        echo "#NASA #Astronomy #PictureOfTheDay"
    }
    

    #bash #ksh #mksh #shellScripting #unix #UnixShell #WebScraping #Scraping #HTML

  22. Since people are going nuts online about how perfect February 2026 is... here you go:

    ~ $ cal feb 2026
       February 2026      
    Su Mo Tu We Th Fr Sa  
     1  2  3  4  5  6  7  
     8  9 10 11 12 13 14  
    15 16 17 18 19 20 21  
    22 23 24 25 26 27 28  
                          
                          
    ~ $ for x in {1900..2050}; do cal feb $x |grep -q "^ 1 " && echo $x; done
    1903
    1914
    1920
    1925
    1931
    1942
    1948
    1953
    1959
    1970
    1976
    1981
    1987
    1998
    2004
    2009
    2015
    2026
    2032
    2037
    2043
    

    #bash #BashOneLiner #ShellOneLiner #shell #UnixShell #unix

  23. #Poll: Curious about people's attitudes towards shell scripting.

    Two part question:

    1. Are you a DEVeloper (or working in a development-heavy role), OTHER-IT worker (such as a sysadmin, architect, anything in a non-development-heavy role), or NON-IT (accountant, doctor, whatever)
    2. Do you HATE shell scripting, are you INDIFferent towards (or ignorant of) shell scripting, or do you LOVE it?

    #Unix #UnixShell #ShellScript #ShellScripting #POSIX #PosixShell #sh #bash #zsh #csh #tcsh #ksh #pdksh #oksh #mksh

  24. In the helpful shell functions department:

    (Requires bc to be installed)

    load() {
        local load=$(uptime |sed -E "s/^.*load averages?: //; s/,.*$//")
        local uname="$(uname)"
        local cpus
        if [[ $1 == -q ]]; then
            echo "$load"
        elif [[ $1 == -i ]]; then
            echo "$load + 0.5" |bc -l |cut -f1 -d.
        else
            case "$uname" in
                Linux)  cpus=$(grep -c ^processor /proc/cpuinfo);;
                *BSD)   cpus=$(sysctl hw.ncpu |tr -dc "0-9\n");;
                *)      warn "load(): assuming 1 cpu, don't know how to get the number in \"$uname\""
                        cpus=1;;
            esac
            local loadPerCPU=$(echo "scale=3; $load / $cpus" |bc -l |sed 's/^\./0./')
            echo "$load ($loadPerCPU per processor ($cpus))"
        fi
    }
    

    #ShellScripting #UnixShell #ShellScripts #bash #ksh #sh

  25. A wild #blog post appears!

    I do some benchmarking of #oksh with nine C compilers on #OpenBSD. Nothing conclusive is discovered, but it is nonetheless a very fun journey.

    briancallahan.net/blog/2021101

    #Unix #Linux #FreeBSD #NetBSD #DragonFlyBSD #BSD #C #compile #compiler #compilers #shell #unixshell #kornshell #ksh

  26. I've probably tooted about this before, but I don't know why this isn't standard.

    It's just so obvious, at least to me. ;)

    ~ $ type mcd
    mcd is a function
    mcd () 
    { 
        [[ -n $1 ]] && mkdir "$1" && cd "$1"
    }
    

    #shell #UnixShell #ShellScripting #sh #bash #ksh #mksh

  27. Umm, why didn't I do this... years ago??

    ~ $ wc pinglog.txt 
      387290  1549160 11618700 pinglog.txt
    ~ $ type commaify
    commaify is a function
    commaify () 
    { 
        local expr='s/([0-9])([0-9]{3}\>)/\1,\2/g';
        sed -E "$expr; $expr; $expr; $expr; $expr; $expr; $expr; $expr; $expr; $expr"
    }
    ~ $ wc pinglog.txt |commaify
      387,290  1,549,160 11,618,700 pinglog.txt
    

    #bash #shell #UNIX #UnixShell #ShellScripting

  28. Should've made this a long time ago:

    function ciglob {
        #case-insensitive glob generator
        echo "$*" |while read -N1 c; do
            case "$c" in
                [a-zA-Z])   echo -n "[${c^^}${c,,}]";;
                *)          echo -n "$c"
            esac
        done
    }
    
    ~ $ ciglob "Hello, world!"
    [Hh][Ee][Ll][Ll][Oo], [Ww][Oo][Rr][Ll][Dd]!
    ~ $ ls -ld $(ciglob documents)
    drwxr-xr-x 52 ~~~ ~~~ 20,480 Apr 10 11:45 Documents
    

    (Not the most useful example, but I did have a use case in mind when I wrote it ;)

    P.S. (This is a valid way to close a parenthesis. Fight me ;)

    #bash #ksh #sh #shell #UnixShell #POSIX #PosixShell #ShellScripting

  29. @witewulf

    Don't tell anyone, but if one escapes the ? metacharacter and *does* pass -? to my tools, it actually *is* a shorthand for --help.

    #nosh #UnixShell

  30. @Migueldeicaza @mholt @film_girl

    I should have kept track of whoever it was commenting the other week about how many machine instructions and conversions to and from machine-readable form it takes to increment a variable by 1.

    _math() {
    _m_opts="$@"
    printf "%s" "$(($_m_opts))"
    }

    ...

    _request_retry_times=$(_math "$_request_retry_times" + 1)

    #UnixShell #ACME

  31. @zigg

    hier(7) on #FreeBSD et al. suggests /usr/local/libexec/${YOURAPP} .

    The logical extension to the XDG Base Directory Specification would likewise be ${HOME}/.local/libexec .

    Of course the . command follows $path , which won't include either of those.

    #UnixShell

  32. @Silversnapples @philheppenstall @Swebb63

    I understand what Phil was saying, and this is exactly why I have the @JdeBP account.

    For the benefit of MastodonApp.UK I can offer this translation from the jargon of Hippie-Unix:

    Phil was clearly stoned in the 1990s.

    'Peace and Love and vi key bindings, baby! "set -o emacs" is just what The Man wants you to type, man!"

    (-:

    #vi #HPUX #HippieCulture #Unix #UnixShell

  33. #Poll: Curious about people's attitudes towards shell scripting.

    Two part question:

    1. Are you a DEVeloper (or working in a development-heavy role), OTHER-IT worker (such as a sysadmin, architect, anything in a non-development-heavy role), or NON-IT (accountant, doctor, whatever)
    2. Do you HATE shell scripting, are you INDIFferent towards (or ignorant of) shell scripting, or do you LOVE it?

    #Unix #UnixShell #ShellScript #ShellScripting #POSIX #PosixShell #sh #bash #zsh #csh #tcsh #ksh #pdksh #oksh #mksh

  34. #Poll: Curious about people's attitudes towards shell scripting.

    Two part question:

    1. Are you a DEVeloper (or working in a development-heavy role), OTHER-IT worker (such as a sysadmin, architect, anything in a non-development-heavy role), or NON-IT (accountant, doctor, whatever)
    2. Do you HATE shell scripting, are you INDIFferent towards (or ignorant of) shell scripting, or do you LOVE it?

    #Unix #UnixShell #ShellScript #ShellScripting #POSIX #PosixShell #sh #bash #zsh #csh #tcsh #ksh #pdksh #oksh #mksh

  35. #Poll: Curious about people's attitudes towards shell scripting.

    Two part question:

    1. Are you a DEVeloper (or working in a development-heavy role), OTHER-IT worker (such as a sysadmin, architect, anything in a non-development-heavy role), or NON-IT (accountant, doctor, whatever)
    2. Do you HATE shell scripting, are you INDIFferent towards (or ignorant of) shell scripting, or do you LOVE it?

    #Unix #UnixShell #ShellScript #ShellScripting #POSIX #PosixShell #sh #bash #zsh #csh #tcsh #ksh #pdksh #oksh #mksh