!esyCFwsvHGqLXuAxSC:matrix.org

Fun Shell Scripting

525 Members
Functional shell scripting knowledge exchange for UNIX experts. MUC bridge: xmpp:fun-shell@conference.movim.eu wikibooks.org/wiki/Bourne_Shell_Scripting tldp.org/LDP/Bash-Beginners-Guide/html github.com/Idnan/bash-guide github.com/lhunath/guide.bash.academy github.com/koalaman/shellcheck github.com/learnbyexample/learn_gnuawk manpages.ubuntu.com/manpages/bionic/man1/checkbashisms.1.html linuxcommand.org Let's review functions in live systems! Share funny snippets or discuss bugs. All variants welcome: BSD, Linux, POSIX, busybox, ash, sash, dash, bash, ksh93, zsh, mksh, pdksh, yash, bosh, posh, csh, tcsh, scsh, es, rash, xshell, ion, nushell, xonsh, oilshell, powershell, fish, elvish, execline, putty, grep, sed, awk. You agree to share snippets under the public domain (unless you otherwise declare it). Report abuse by typing !modhelp Examples shellscript.sh github.com/openwrt/openwrt/tree/master/package/base-files/files codeberg.org/Sapphire/sapphire-butler/src/branch/master/departments github.com/pacstall/pacstall-programs60 Servers

Load older messages


SenderMessageTime
15 Jan 2025
@aral:matrix.orgaralhere's my set of scripts: xml-format.sh: performs XML linting on $1 xml-guarded-format.sh: invokes xml-format.sh if and only if the extension of $1 matches any extension provided as a further command line argument $2, $3, ... xml-format-all.sh: find all files recursively in working dir and execute xml-guarded-format on them, passing in as allowed extensions two defaults (xml, rels) and all further extensions provided on the command line17:12:04
@aral:matrix.orgaral

xml-format.sh:

#!/bin/sh

if [ -z $1 ]; then
	echo "need to provide a command line parameter"
	exit 1
fi

if [ ! -e $1 ]; then
	echo "provided argument \"$1\" does not exist"
	exit 1
fi

# extension=`echo $1 | sed -r 's/[^.]*(\.([^.]*))*$/\2/g'`
#if [ "$extension" != "xml" ]; then
#	echo "script may only be called on xml files, invalid extension \"$extension\""
#	exit 1
#fi

if [ ! -e $1 ]; then
	echo "provided argument \"$1\" does not exist"
	exit 1
fi

# Old instruction for echo:
# echo "XMLLINT_INDENT=\$'\t' xmllint --format \"$1\" > \"$1.formatted\"; mv \"$1.formatted\" \"$1\""

# New instructions: echo and execute
echo "export XMLLINT_INDENT='	'; xmllint --format \"$1\" > \"$1.formatted\"; mv \"$1.formatted\" \"$1\""

export XMLLINT_INDENT='	';
xmllint --format "$1" > "$1.formatted";

# Safeguard: do not overwrite original file unless xmllint succeeded
if [ "$?" = "0" ]; then
  mv "$1.formatted" "$1"
else
  rm "$1.formatted"
fi
17:12:29
@aral:matrix.orgaral

guarded-xml-format.sh:

#!/bin/sh

if [ -z $1 ]; then
	echo "need to provide a command line parameter"
	exit 1
fi

if [ ! -e $1 ]; then
	echo "provided argument \"$1\" does not exist"
	exit 1
fi

SCRIPT_PATH=`dirname "$0"`
# echo "SCRIPT_PATH is $SCRIPT_PATH"

EXTENSIONS=""
ALLOWED_EXTENSION="false"

FILE=""
extension="(uninitialized)"

for arg in "$@" ; do
    if [ "$FILE" = "" ]; then
        FILE=$arg
        extension=`echo $FILE | sed -r 's/[^.]*(\.([^.]*))*$/\2/g'`
#         echo "for file $FILE detected extension: $extension"
    else
#         echo "allowed extension: $arg"
        if [ "$EXTENSIONS" != "" ]; then
            EXTENSIONS="$EXTENSIONS, "
        fi
        EXTENSIONS="$EXTENSIONS\"$arg\""
        if [ "$extension" = "$arg" ]; then
#             echo "file name matches allowed extension $arg"
            ALLOWED_EXTENSION="true"
break;
        fi
    fi
done

if [ "$ALLOWED_EXTENSION" = "true" ]; then
#     echo "found an allowed extension - if it safe to invoke $SCRIPT_PATH/xml-format.sh for $FILE"
    "$SCRIPT_PATH/xml-format.sh" $FILE
else
#     echo "script may only be called on files with extensions [$EXTENSIONS], invalid extension \"$extension\" on $FILE"
    exit 1
fi
17:13:00
@aral:matrix.orgaral* here's my set of scripts: xml-format.sh: performs XML linting on $1 guarded-xml-format.sh: invokes xml-format.sh if and only if the extension of $1 matches any extension provided as a further command line argument $2, $3, ... xml-format-all.sh: find all files recursively in working dir and execute xml-guarded-format on them, passing in as allowed extensions two defaults (xml, rels) and all further extensions provided on the command line17:13:10
@aral:matrix.orgaral

xml-format-all.sh:

#!/bin/sh

SCRIPT_PATH=`dirname "$0"`
# echo "SCRIPT_PATH is $SCRIPT_PATH"

EXTENSIONS="xml rels"
EXTENSIONS_FOR_ECHO="\"xml\", \"rels\""
for arg in "$@" ; do
    if [ "$arg" != "xml" ] && [ "$arg" != "rels" ]; then
        EXTENSIONS="$EXTENSIONS $arg"
        EXTENSIONS_FOR_ECHO="$EXTENSIONS_FOR_ECHO, \"$arg\""
    else
        echo "ignoring default extension [\"xml\" or \"rels\"]"
    fi
done

echo "applying xmllint recursively to all files in folder ending in any of [$EXTENSIONS_FOR_ECHO]"
# echo "find . -type f -exec $SCRIPT_PATH/guarded-xml-format.sh {} $EXTENSIONS \;"
find . -type f -exec "$SCRIPT_PATH/guarded-xml-format.sh" {} $EXTENSIONS \;
17:13:34
@bkil:matrix.orgbkil
In reply to@m-yusuf:matrix.org
Beginner Q: Seeking a website to get started with Hands-on Bash scripting ? Any inputs are appreciated !
https://github.com/bkil/shell-fun#documentation
17:19:13
@emanresu3:matrix.orgemanresu3
In reply to @euro20179:matrix.org
well ${0%/*} is guaranteed to remove the slash but the former, first finds the basename with 0##*/ and a question mark for some reason, then deletes that from $0 with $0%
the only real difference I see is when ${0} would be empty, which is already rare:
p='/'
"${p%?"${p##*/?}"}"  # '/'
"${p%/*}/"           # '/'
"$(dirname "$p")"    # '/'

p=''
"${p%?"${p##*/?}"}"  # ''
"${p%/*}/"           # '/'
"$(dirname "$p")"    # '.'
17:27:24
@euro20179:matrix.orgeuro20179oh interesting17:27:41
@euro20179:matrix.orgeuro20179

sh-5.2$ p='/'
sh-5.2$ echo "${p%/*}"

sh-5.2$

17:28:49
@euro20179:matrix.orgeuro20179 *

sh-5.2$ p='/'
sh-5.2$ echo "${p%/*}"

sh-5.2$

17:28:52
@euro20179:matrix.orgeuro20179idk it gave me blank17:28:57
@euro20179:matrix.orgeuro20179what shell were you using17:29:02
@euro20179:matrix.orgeuro20179oh because you put the extra slash17:29:23
@euro20179:matrix.orgeuro20179nvm17:29:23
@otto.postalis:matrix.org@otto.postalis:matrix.org joined the room.18:24:17
@otto.postalis:matrix.org@otto.postalis:matrix.org left the room.18:24:21
@emanresu3:matrix.orgemanresu3 Oh I see why I used "${p%?"${p##*/?}"}". It gets the dirname if the path has a trailing / (if it's a directory path), unlike "${p%/*}/". However 1) ${0} shouldn't have a trailing / so it shouldn't matter there, and 2) it doesn't account for multiple trailing / (e.g. /path//) unlike dirname 18:26:28
@euro20179:matrix.orgeuro20179oh i see18:31:00
@benjaminedwardwebb:envs.netbenwebb Does anyone here have tips on how to evaluate the performance of a bash function or builtin? My current strategy is simply time for _ in {0..n}; do f; done, but I'd love to find out there is something like hyperfine but for bash builtins 22:14:15
@meow:re128.orgmeow ✨
In reply to @benjaminedwardwebb:envs.net
Does anyone here have tips on how to evaluate the performance of a bash function or builtin? My current strategy is simply time for _ in {0..n}; do f; done, but I'd love to find out there is something like hyperfine but for bash builtins
and.. what is "hyperfine"?
22:35:14
@benjaminedwardwebb:envs.netbenwebba benchmarking tool with great documentation https://github.com/sharkdp/hyperfine?tab=readme-ov-file#shell-functions-and-aliases22:37:57
@benjaminedwardwebb:envs.netbenwebbI feel pretty silly now. I was looking at the man page but didn't check the README until I went to grab a link to it ... still would be interested to hear any tips or stories folks have about performance evaluation on shell builtins, though22:39:22
@meow:re128.orgmeow ✨
In reply to @benjaminedwardwebb:envs.net
a benchmarking tool with great documentation https://github.com/sharkdp/hyperfine?tab=readme-ov-file#shell-functions-and-aliases
hm.. would be nice to write sm POSIX-compatible in sh
22:40:30
@meow:re128.orgmeow ✨ but.. afair, time shouldnt even be built into sh according to standard 22:41:17
@meow:re128.orgmeow ✨maybe, its possible to use procfs for busy-waiting and counting time22:42:23
@meow:re128.orgmeow ✨but im unsure22:42:34
@benjaminedwardwebb:envs.netbenwebb I'm surprised time isn't posix! 22:42:51
@benjaminedwardwebb:envs.netbenwebbbut I guess I'm often surprised when something I rely on isn't posix22:43:08
@euro20179:matrix.orgeuro20179i mean there's a lot of things that aren't built into the shell according to posix22:44:38
@euro20179:matrix.orgeuro20179though tbf i thought time was22:44:46

There are no newer messages yet.


Back to Room ListRoom Version: 9