aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2016-08-20 17:27:04 +1200
committerTom Ryder <tom@sanctum.geek.nz>2016-08-20 17:27:04 +1200
commit78ca825a27ea02ed17be226f253cecb0e3a71daa (patch)
tree2ba1c404e97fbde9386c4c1e3926c549d9b72a2b
parentPort fnl() to POSIX sh script fnl(1) (diff)
downloaddotfiles-78ca825a27ea02ed17be226f253cecb0e3a71daa.tar.gz
dotfiles-78ca825a27ea02ed17be226f253cecb0e3a71daa.zip
Port path() to POSIX sh
That was a lot easier than I thought
-rw-r--r--README.markdown2
-rw-r--r--bash/bashrc.d/path.bash180
-rw-r--r--sh/shrc.d/path.sh93
3 files changed, 94 insertions, 181 deletions
diff --git a/README.markdown b/README.markdown
index 40556ef1..4108914d 100644
--- a/README.markdown
+++ b/README.markdown
@@ -188,6 +188,7 @@ in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include:
* `mkcd()` creates a directory and changes into it.
* `mysql()` allows shortcuts to MySQL configuration files stored in
`~/.mysql`.
+* `path()` manages the contents of `PATH` conveniently.
* `pd()` changes to the argument's parent directory.
* `pwgen()` generates just one decent password with `pwgen(1)`.
* `rcsdiff()` forces a unified format for `rcsdiff(1)`.
@@ -208,7 +209,6 @@ There are a few other little tricks defined for other shells, mostly in
`bash/bashrc.d`:
* `keep()` stores ad-hoc shell functions and variables.
-* `path()` manages the contents of `PATH` conveniently.
* `prompt()` sets up my interactive prompt.
* `pushd()` adds a default destination of `$HOME` to the `pushd` builtin.
* `vared()` allows interactively editing a variable with Readline, emulating
diff --git a/bash/bashrc.d/path.bash b/bash/bashrc.d/path.bash
deleted file mode 100644
index 61bf73c0..00000000
--- a/bash/bashrc.d/path.bash
+++ /dev/null
@@ -1,180 +0,0 @@
-# Function to manage contents of PATH variable within the current shell
-path() {
-
- # Figure out command being called
- local pathcmd
- if (($#)) ; then
- pathcmd=$1
- shift
- else
- pathcmd=list
- fi
-
- # Switch between commands
- case $pathcmd in
-
- # Print help output (also done if command not found)
- help|h|-h|--help|-\?)
- while IFS= read -r line ; do
- printf '%s\n' "$line"
- done <<EOF
-$FUNCNAME: Manage contents of PATH variable
-
-USAGE:
- $FUNCNAME h[elp]
- Print this help message (also done if command not found)
- $FUNCNAME l[ist]
- Print the current directories in PATH, one per line (default command)
- $FUNCNAME i[nsert] DIR
- Add a directory to the front of PATH, checking for existence and uniqueness
- $FUNCNAME a[ppend] DIR
- Add a directory to the end of PATH, checking for existence and uniqueness
- $FUNCNAME r[emove] DIR
- Remove all instances of a directory from PATH
-
-INTERNALS:
- $FUNCNAME s[et] [DIR1 [DIR2...]]
- Set the PATH to the given directories without checking existence or uniqueness
- $FUNCNAME c[heck] DIR
- Return whether DIR is a component of PATH
-
-EOF
- ;;
-
- # Print the current contents of the path
- list|l)
- local -a patharr
- IFS=: read -a patharr < <(printf '%s\n' "$PATH")
- if ((${#patharr[@]})) ; then
- printf '%s\n' "${patharr[@]}"
- fi
- ;;
-
- # Add a directory to the front of PATH, checking for existence and uniqueness
- insert|i)
- local -a patharr
- IFS=: read -a patharr < <(printf '%s\n' "$PATH")
- local dirname
- dirname=$1
- [[ $dirname == / ]] || dirname=${dirname%/}
- if [[ -z $dirname ]] ; then
- printf 'bash: %s: need a directory path to insert\n' \
- "$FUNCNAME" >&2
- return 1
- fi
- if [[ ! -d $dirname ]] ; then
- printf 'bash: %s: %s not a directory\n' \
- "$FUNCNAME" "$dirname" >&2
- return 1
- fi
- if [[ $dirname == *:* ]] ; then
- printf 'bash: %s: Cannot add insert directory %s with colon in name\n' \
- "$FUNCNAME" "$dirname" >&2
- return 1
- fi
- if path check "$dirname" ; then
- printf 'bash: %s: %s already in PATH\n' \
- "$FUNCNAME" "$dirname" >&2
- return 1
- fi
- patharr=("$dirname" "${patharr[@]}")
- path set "${patharr[@]}"
- ;;
-
- # Add a directory to the end of PATH, checking for existence and uniqueness
- append|add|a)
- local -a patharr
- IFS=: read -a patharr < <(printf '%s\n' "$PATH")
- local dirname
- dirname=$1
- [[ $dirname == / ]] || dirname=${dirname%/}
- if [[ -z $dirname ]] ; then
- printf 'bash: %s: need a directory path to append\n' \
- "$FUNCNAME" >&2
- return 1
- fi
- if [[ ! -d $dirname ]] ; then
- printf 'bash: %s: %s not a directory\n' \
- "$FUNCNAME" "$dirname" >&2
- return 1
- fi
- if [[ $dirname == *:* ]] ; then
- printf 'bash: %s: Cannot append directory %s with colon in name\n' \
- "$FUNCNAME" "$dirname" >&2
- return 1
- fi
- if path check "$dirname" ; then
- printf 'bash: %s: %s already in PATH\n' \
- "$FUNCNAME" "$dirname" >&2
- return 1
- fi
- patharr[${#patharr[@]}]=$dirname
- path set "${patharr[@]}"
- ;;
-
- # Remove all instances of a directory from PATH
- remove|rm|r)
- local -a patharr
- IFS=: read -a patharr < <(printf '%s\n' "$PATH")
- local dirname
- dirname=$1
- [[ $dirname == / ]] || dirname=${dirname%/}
- if [[ -z $dirname ]] ; then
- printf 'bash: %s: need a directory path to remove\n' \
- "$FUNCNAME" >&2
- return 1
- fi
- if ! path check "$dirname" ; then
- printf 'bash: %s: %s not in PATH\n' \
- "$FUNCNAME" "$dirname" >&2
- return 1
- fi
- local -a newpatharr
- local part
- for part in "${patharr[@]}" ; do
- [[ $dirname == "$part" ]] && continue
- newpatharr[${#newpatharr[@]}]=$part
- done
- path set "${newpatharr[@]}"
- ;;
-
- # Set the PATH to the given directories without checking existence or uniqueness
- set|s)
- local -a newpatharr
- local dirname
- for dirname ; do
- newpatharr[${#newpatharr[@]}]=$dirname
- done
- PATH=$(IFS=: ; printf '%s' "${newpatharr[*]}")
- ;;
-
- # Return whether directory is a component of PATH
- check|c)
- local -a patharr
- IFS=: read -a patharr < <(printf '%s\n' "$PATH")
- local dirname
- dirname=$1
- [[ $dirname == / ]] || dirname=${dirname%/}
- if [[ -z $dirname ]] ; then
- printf 'bash: %s: need a directory path to check\n' \
- "$FUNCNAME" >&2
- return 1
- fi
- local part
- for part in "${patharr[@]}" ; do
- if [[ $dirname == "$part" ]] ; then
- return 0
- fi
- done
- return 1
- ;;
-
- # Unknown command
- *)
- printf 'bash: %s: Unknown command %s\n' \
- "$FUNCNAME" "$pathcmd" >&2
- path help >&2
- return 1
- ;;
- esac
-}
diff --git a/sh/shrc.d/path.sh b/sh/shrc.d/path.sh
new file mode 100644
index 00000000..22374310
--- /dev/null
+++ b/sh/shrc.d/path.sh
@@ -0,0 +1,93 @@
+# Function to manage contents of PATH variable within the current shell
+path() {
+
+ # The second argument, the directory, can never have a colon
+ case $2 in
+ *:*)
+ printf >&2 'path(): Illegal colon in given directory\n'
+ return 2
+ ;;
+ esac
+
+ # Check first argument to figure out operation
+ case $1 in
+
+ # List current directories in $PATH
+ list|'') (
+ path=$PATH:
+ while [ -n "$path" ] ; do
+ dir=${path%%:*}
+ path=${path#*:}
+ [ -n "$dir" ] || continue
+ printf '%s\n' "$dir"
+ done
+ ) ;;
+
+ # Add a directory at the start of $PATH
+ insert)
+ if path check "$2" ; then
+ printf >&2 'path(): %s already in $PATH\n'
+ return 1
+ fi
+ PATH=${2}${PATH:+:"$PATH"}
+ ;;
+
+ # Add a directory to the end of $PATH
+ append)
+ if path check "$2" ; then
+ printf >&2 'path(): %s already in $PATH\n'
+ return 1
+ fi
+ PATH=${PATH:+"$PATH":}${2}
+ ;;
+
+ # Remove a directory from $PATH
+ remove)
+ if ! path check "$2" ; then
+ printf >&2 'path(): %s not in $PATH\n'
+ return 1
+ fi
+ PATH=$(
+ path=:$path:
+ path=${path%%:"$2":*}:${path#*:"$2":}
+ path=${path#:}
+ path=${path%:}
+ printf '%s\n' "$path"
+ )
+ ;;
+
+ # Check whether a directory is in $PATH
+ check) (
+ path=:$PATH:
+ [ "$path" != "${path%:"$2":*}" ]
+ ) ;;
+
+ # Print help output (also done if command not found)
+ help)
+ cat <<'EOF'
+path(): Manage contents of PATH variable
+
+USAGE:
+ path [list]
+ Print the current directories in PATH, one per line (default command)
+ path insert DIR
+ Add a directory to the front of PATH
+ path append DIR
+ Add a directory to the end of PATH
+ path remove DIR
+ Remove directory from PATH
+ path check DIR
+ Return whether DIR is a component of PATH
+ path help
+ Print this help message (also done if command not found)
+EOF
+ ;;
+
+ # Command not found
+ *)
+ printf >&2 'path(): Unknown command\n'
+ path help
+ return 2
+ ;;
+ esac
+}