- Added quoting to handle spaces in environment values in commit 50852b33
(#1007, #1008). However, quoting is only needed for eval mode.
In regular mode, quoting should not be part of the output, instead it
should be done on the caller side.
251 lines
6.5 KiB
Bash
Executable File
251 lines
6.5 KiB
Bash
Executable File
#!/bin/sh
|
|
#------------------------------------------------------------------------------
|
|
# ========= |
|
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
# \\ / O peration |
|
|
# \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
# \\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
|
#-------------------------------------------------------------------------------
|
|
# License
|
|
# This file is part of OpenFOAM, licensed under GNU General Public License
|
|
# <http://www.gnu.org/licenses/>.
|
|
#
|
|
# Script
|
|
# foamCleanPath
|
|
#
|
|
# Description
|
|
# Usage: foamCleanPath [OPTION] path [filter] .. [filter]
|
|
# foamCleanPath [OPTION] -env=name [filter] .. [filter]
|
|
#
|
|
# Prints its argument (which should be a ':' separated path)
|
|
# without the following:
|
|
# - duplicate elements
|
|
# - elements matching the specified filter(s)
|
|
# - inaccessible directories (with the -strip option)
|
|
#
|
|
# Note
|
|
# - false matches possible when the filter contains '.' (sed regex) etc.
|
|
# - a single composite filter can be passed in. This composite filter
|
|
# is assumed to be delimited by whitespace, colons or semi-colons.
|
|
#
|
|
# Examples for cleaning the path:
|
|
#
|
|
# - Using explicit arguments
|
|
# cleaned=$(foamCleanPath "$PATH" dir1:dir2) && PATH=$cleaned
|
|
#
|
|
# - Variable to clean passed as an option
|
|
# cleaned=$(foamCleanPath -env=PATH dir1:dir2) && PATH=$cleaned
|
|
#
|
|
# - Using shell evaluation for the output
|
|
# eval $(foamCleanPath -sh=PATH $PATH" dir1:dir2)
|
|
# eval "$(foamCleanPath -sh=PATH -env=PATH dir1:dir2)"
|
|
# eval "$(foamCleanPath -sh-env=PATH dir1:dir2)"
|
|
#
|
|
# - Similarly for c-shell
|
|
# eval `foamCleanPath -csh-env=PATH dir1:dir2`
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
usage() {
|
|
cat <<USAGE 1>&2
|
|
Usage: foamCleanPath [OPTION] path [filter] .. [filter]
|
|
foamCleanPath [OPTION] -env=name [filter] .. [filter]
|
|
options:
|
|
-csh=NAME Produce 'setenv NAME ...' output for csh eval
|
|
-sh=NAME Produce 'NAME=...' output for sh eval
|
|
-csh-env=NAME As per -csh, with -env for initial content
|
|
-sh-env=NAME As per -sh, with -env for initial content
|
|
-env=NAME Evaluate NAME to obtain initial content
|
|
-debug Print debug information to stderr
|
|
-strip Remove inaccessible directories
|
|
-verbose Report some progress (input, output, ...)
|
|
-help Print the usage
|
|
|
|
Prints its argument (which should be a ':' separated list) cleansed from
|
|
* duplicate elements
|
|
* elements whose start matches one of the filters
|
|
* inaccessible directories (the -strip option)
|
|
|
|
Exit status
|
|
0 on success
|
|
1 general error
|
|
2 initial value of 'path' is empty
|
|
|
|
USAGE
|
|
exit 1
|
|
}
|
|
|
|
# Report error and exit
|
|
die()
|
|
{
|
|
exec 1>&2
|
|
echo
|
|
echo "Error encountered:"
|
|
while [ "$#" -ge 1 ]; do echo " $1"; shift; done
|
|
echo
|
|
echo "See 'foamCleanPath -help' for usage"
|
|
echo
|
|
exit 1
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Input and outputs
|
|
unset dirList shellOutput
|
|
|
|
# Parse options
|
|
unset optDebug optEnvName optStrip optVerbose
|
|
while [ "$#" -gt 0 ]
|
|
do
|
|
case "$1" in
|
|
-h | -help*)
|
|
usage
|
|
;;
|
|
-csh=* | -sh=* | -csh-env=* | -sh-env=*)
|
|
name="${1#*=}"
|
|
[ -n "$name" ] || die "Option '$1' missing an ENVNAME"
|
|
|
|
# Output prefix
|
|
case "$1" in
|
|
-csh*)
|
|
shellOutput="setenv $name " # eg, "setenv PATH xyz"
|
|
;;
|
|
*)
|
|
shellOutput="$name=" # eg, "PATH=xyz"
|
|
;;
|
|
esac
|
|
|
|
# For (-csh-env | -sh-env) also use name for input evaluation
|
|
case "$1" in
|
|
*-env=*)
|
|
optEnvName="$name"
|
|
;;
|
|
esac
|
|
;;
|
|
-env=*)
|
|
name="${1#*=}"
|
|
[ -n "$name" ] || die "Option '$1' missing an ENVNAME"
|
|
optEnvName="$name"
|
|
;;
|
|
-debug)
|
|
optDebug=true
|
|
;;
|
|
-strip)
|
|
optStrip=true
|
|
;;
|
|
-verbose)
|
|
optVerbose=true
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
|
|
# Basic checks
|
|
if [ -n "$optEnvName" ]
|
|
then
|
|
eval "dirList=\$$optEnvName"
|
|
elif [ "$#" -ge 1 ]
|
|
then
|
|
dirList="$1"
|
|
shift
|
|
else
|
|
die "Requires at least one argument, or use the -env option"
|
|
fi
|
|
|
|
[ -n "$dirList" ] || exit 2 # Quick exit on empty 'dirList'
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Debugging (optional)
|
|
if [ -n "$optDebug" ]
|
|
then
|
|
printDebug() { while [ "$#" -ge 1 ]; do echo "$1" 1>&2; shift; done; }
|
|
else
|
|
printDebug() { true; } # No-op
|
|
fi
|
|
|
|
# Optional test for directory existence
|
|
if [ -n "$optStrip" ]
|
|
then
|
|
isDir() { test -d "$1"; } # Check for directory existence
|
|
else
|
|
isDir() { test -n "$1"; } # Only check for non-zero string
|
|
fi
|
|
|
|
# The "filter ... filterN" may have been passed as a single parameter
|
|
# or may contain ':' separators.
|
|
# Currently (OCT-2018) also accept split on whitespace too.
|
|
|
|
oldIFS="$IFS" # Preserve initial IFS
|
|
IFS=':; ' # Split on colon, semicolon, whitespace
|
|
set -- $*
|
|
|
|
if [ -n "$optVerbose" ]
|
|
then
|
|
echo "clean: $dirList" 1>&2
|
|
echo "with: $@" 1>&2
|
|
fi
|
|
|
|
printDebug "input>$dirList<"
|
|
|
|
# Apply filters via sed. Path and filter cannot contain '?'.
|
|
for filter
|
|
do
|
|
if [ -n "$filter" ]
|
|
then
|
|
printDebug "remove>$filter<"
|
|
dirList=$(echo "$dirList:" | sed -e "s?${filter}[^:]*:??g")
|
|
fi
|
|
done
|
|
printDebug "intermediate>$dirList<"
|
|
|
|
IFS=':' # Split on colon. No split on whitespace.
|
|
set -- $dirList
|
|
|
|
# Rebuild the list
|
|
unset dirList
|
|
for dir
|
|
do
|
|
printDebug "check>$dir< in $dirList"
|
|
if isDir "$dir"
|
|
then
|
|
# Detect duplicates (ie, dir already in the list)
|
|
duplicate=$(echo ":$dirList:" | sed -ne '\?:'"$dir"':?p')
|
|
|
|
if [ -n "$duplicate" ]
|
|
then
|
|
printDebug "duplicate>$dir<"
|
|
else
|
|
dirList="${dirList}${dirList:+:}$dir"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
IFS="$oldIFS" # Restore initial IFS
|
|
|
|
# Output:
|
|
#
|
|
# For eval mode, add quotes around the argument.
|
|
# - eg, <. PATH="path1;path2;...">
|
|
#
|
|
# With regular output, any quoting would be done on the caller side.
|
|
# - eg, <cleaned="($foamClean -env=PATH foo)
|
|
|
|
printDebug "output>$dirList<"
|
|
if [ -n "$optVerbose" ]
|
|
then
|
|
echo "output: \"$dirList\"" 1>&2
|
|
fi
|
|
|
|
if [ -n "$shellOutput" ]
|
|
then
|
|
echo "$shellOutput\"$dirList\""
|
|
else
|
|
echo "$dirList"
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|