From 267bcc9dc9ed7f59430d811da472a6da29c7e5e2 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 20 Sep 2016 13:35:22 +1200 Subject: Add mex(1df) --- README.markdown | 1 + bin/mex | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ man/man1/mex.1df | 22 ++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100755 bin/mex create mode 100644 man/man1/mex.1df diff --git a/README.markdown b/README.markdown index 3e566177..66864981 100644 --- a/README.markdown +++ b/README.markdown @@ -443,6 +443,7 @@ Installed by the `install-bin` target: * `maybe(1df)` is like `true(1)` or `false(1)`; given a probability of success, it exits with success or failure. Good for quick tests. +* `mex(1df)` makes given filenames in `$PATH` executable. * `mftl(1df)` finds usable-looking targets in Makefiles. * `mkcp(1df)` creates a directory and copies preceding arguments into it. * `mkmv(1df)` creates a directory and moves preceding arguments into it. diff --git a/bin/mex b/bin/mex new file mode 100755 index 00000000..005149d8 --- /dev/null +++ b/bin/mex @@ -0,0 +1,53 @@ +#!/bin/sh +# Make the first non-executable instance of files with the given names in $PATH +# executable +self=mex + +# Check we have at least one argument +if [ "$#" -eq 0 ] ; then + printf >&2 '%s: At least one name required\n' "$self" + exit 2 +fi + +# Iterate through the given names +for name ; do + + # Clear the found variable + found= + + # Start iterating through $PATH, with colon prefix/suffix to correctly + # handle the fenceposts + path=:$PATH: + while [ -n "$path" ] ; do + + # Pop the first directory off $path into $dir + dir=${path%%:*} + path=${path#*:} + + # Check $dir is non-null + [ -n "$dir" ] || continue + + # If a file with the needed name exists in the directory and isn't + # executable, we've found our candidate and can stop iterating + if [ -f "$dir"/"$name" ] && ! [ -x "$dir"/"$name" ] ; then + found=$dir/$name + break + fi + done + + # If the "found" variable was defined to something, we'll try to change its + # permissions + if [ -n "$found" ] ; then + chmod +x -- "$found" || ex=1 + + # If not, we'll report that we couldn't find it, and flag an error for the + # exit status + else + printf >&2 '%s: No non-executable name "%s" in PATH\n' "$self" "$name" + ex=1 + fi +done + +# We exit 1 if any of the names weren't found or if changing their permissions +# failed +exit "${ex:-0}" diff --git a/man/man1/mex.1df b/man/man1/mex.1df new file mode 100644 index 00000000..0fa584da --- /dev/null +++ b/man/man1/mex.1df @@ -0,0 +1,22 @@ +.TH MEX 1df "September 2016" "Manual page for mex" +.SH NAME +.B mex +\- make first instance of filenames in $PATH executable +.SH USAGE +.B mex +name +.br +.B mex +name1 name2 name3 +.br +PATH=/foo:/bar/baz +name +.SH DESCRIPTION +Iterate through the contents of the PATH variable looking for files with any of +the specified names that do not have the executable permissions bit set, and +try to set it if found. Exit nonzero if any of the names were not found, or if +any of the permissions changes failed. +.SH SEE ALSO +chmod(1), eds(1df) +.SH AUTHOR +Tom Ryder -- cgit v1.2.3