gemini.git

going-flying.com gemini git repository

summary

tree

log

refs

70f567250ffdbffb9047c9b214512f1c549a7603 - Matthew Ernisse - 1675787445

new post

view tree

view raw

diff --git a/users/mernisse/articles/32.gmi b/users/mernisse/articles/32.gmi
new file mode 100644
index 0000000..de85bfa
--- /dev/null
+++ b/users/mernisse/articles/32.gmi
@@ -0,0 +1,125 @@
+---
+Title: Re: Wrapper Script Etiquette
+Date: 02/07/2023 11:24
+In-Reply-To: gemini://thrig.me/blog/2023/02/05/wrapper-script-etiquette.gmi
+
+I stumbled upon some musing[1] about different form simple shell scripts
+can take and had some thoughts.  Now my first rule of programming is to
+follow the style of the team you're working with.  If you think something
+should be different, you must convince the team instead of doing your own
+thing in the corner.  It's more important that the team be able to survive
+without you than it is to be "right".  If you are working alone then as a
+team of 1, you just need to convince yourself.  Once you have satisfied the
+above, the next rule is to keep it as simple and straightforward as possible.
+To paraphrase something I heard many years ago, you have to be smarter than
+the author to debug a thing so try not to be your cleverest when you are
+writing something else you may not be qualified to maintain it.  For some
+final context before I begin my more specific thoughts I'm used to working
+in mixed environments so my goal with shell scripts specifically is  maximal
+portability.  I prefer POSIX shell to the point that I'd rather inline Python
+or Perl than resort to bash-isms.  My targets are typically MacOS/bash,
+Linux/bash, Linux/dash, and BSD/pdksh.
+
+
+These were the examples given in the original article.
+
+=> gemini://thrig.me/blog/2023/02/05/wrapper-script-etiquette.gmi [1]
+
+## pa
+
+```
+	ping -f "$@"
+```
+
+## re
+
+```
+	#!/bin/sh
+	ping -f "$@"
+```
+ 
+## ci
+
+```
+	#!/bin/sh
+	/sbin/ping -f "$@"
+```
+
+## vo
+
+```
+	#!/bin/sh
+	exec /sbin/ping -f "$@"
+```
+
+Now in these specific examples you would need super-user privileges to
+run any of these commands (I tested on MacOS, Debian Linux and OpenBSD)
+but I'm going to assume the original author didn't intend to limit the
+scope of their comments to scripts requiring elevated privileges to run.
+
+The first example (pa) is not even a shell script.
+
+Of the remaining, I'd prefer the second form (re) the most.  It is simple,
+lets the shell do most of the work and doesn't impose unnecessary portability
+problems.  The author argues that hard-coding absolute path names provides
+some additional security but for maintainability's sake I'd rather choose to
+control $PATH in the script if it was critical and still allow the shell to
+resolve locations itself.  It is certainly easier to read and maintain
+than having /full/path/to/file everywhere.  More critically I think the
+security argument is a bit of a fallacy.  Defense is depth is a good strategy
+but there's no point in digging a moat inside the vault.  If an attacker has
+gained control of your system sufficiently to modify the environment of your
+running shell (to change your $PATH) and inject an executable binary on the
+filesystem then the game was already over.  Now there may be some cases
+where you absolutely want a specifically installed version of a program
+to be run, and then you may find yourself hard-coding a full path to it
+(perhaps it is located in a directory not in your shell's $PATH and you
+don't want to accidentally execute other binaries later in the script from
+that directory) but for system utilities letting the shell do the lookup
+for you is not unreasonable.  As to the complaint of extra work, Most shells
+cache the lookups so the penalty is very low and the portability gains are
+very high.  You certainly don't want to find yourself doing this.
+
+```
+case $(uname -s) in
+	Darwin)
+		/usr/bin/foo
+		;;
+
+	OpenBSD)
+		/bin/foo
+		;;
+
+	*)
+		/usr/local/bin/foo
+		;;
+esac
+```
+
+Towards the final form (vo), and generally as far as using exec goes, the
+author elucidates a frustration with an untidy pstree(1) output and frankly
+I find that argument unpersuasive.  More important than an aesthetic situation
+that might be encountered rarely (are you often looking at the process table
+in another window while running a script?) is being able to figure out where a
+hung program came from.  I've had many situations where a remote filesystem
+hangs and a bunch of programs back up blocked waiting on IO and if they all
+were just exec'd binaries over shell scripts I'd never be able to say track
+down the cron(8) job that fired them off.  Exec also obviates the ability for
+any sort of cleanup or trap handler functions from running leading to the
+question, why is this a shell script?  If you truly are making a script that
+is literally as shown in vo above, you should probably just use an alias or a
+function in your .profile instead.  You save yourself the performance and
+security concerns of executing a new copy of the shell entirely there.
+
+Hopefully my thoughts make it clear that I value simplicity, portability and
+maintainability in most things, and doubly so in shell scripts.  I have
+scripts that have roots over 20 years ago and they generally get polished down
+to be as short, and simple as possible.  If you don't want to find yourself
+mad at it at some point in the future, leave as few traps for yourself as you
+can.
+
+For further reading one might find an annotated view of my .profile[2]
+interesting.
+
+=> /~mernisse/14.gmi [2]
+