314 lines
8.5 KiB
Bash
Executable File
314 lines
8.5 KiB
Bash
Executable File
#!/bin/sh
|
|
#------------------------------------------------------------------------------
|
|
# ========= |
|
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
# \\ / O peration |
|
|
# \\ / A nd | www.openfoam.com
|
|
# \\/ M anipulation |
|
|
#------------------------------------------------------------------------------
|
|
# Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
# Copyright (C) 2017-2021 OpenCFD Ltd.
|
|
#------------------------------------------------------------------------------
|
|
# License
|
|
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
|
#
|
|
# 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.
|
|
# - will not filter out standard system paths (/usr/bin etc)
|
|
#
|
|
# 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)"
|
|
# eval "$(foamCleanPath -sh-path dir1:dir2)"
|
|
#
|
|
# - Similarly for c-shell
|
|
# eval `foamCleanPath -csh-path dir1:dir2`
|
|
#
|
|
# For library paths, it is suggested to use -sh-lib, or -csh-lib.
|
|
# The will use DYLD_LIBRARY_PATH instead of LD_LIBRARY_PATH on Darwin.
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
printHelp() {
|
|
cat<<USAGE
|
|
|
|
Usage: foamCleanPath [OPTION] ENV [filter] .. [filter]
|
|
foamCleanPath [OPTION] -env=name [filter] .. [filter]
|
|
options:
|
|
-env=NAME Evaluate NAME to obtain initial content,
|
|
Accepts "-env=-path", "-env=-lib" shortcuts for PATH
|
|
and LD_LIBRARY_PATH (DYLD_LIBRARY_PATH on Darwin)
|
|
-sh=NAME Produce 'NAME=...' output for sh eval
|
|
-csh=NAME Produce 'setenv NAME ...' output for csh eval
|
|
-sh-env=NAME Same as -sh=NAME -env=NAME
|
|
-csh-env=NAME Same as -csh=NAME -env=NAME
|
|
-sh-path | -csh-path Same as -[c]sh-env=PATH
|
|
-sh-lib | -csh-lib Same as -[c]sh-env=LD_LIBRARY_PATH
|
|
or DYLD_LIBRARY_PATH on Darwin
|
|
-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 0 # A clean exit
|
|
}
|
|
|
|
# Report error and exit
|
|
die()
|
|
{
|
|
exec 1>&2
|
|
echo
|
|
echo "Error encountered:"
|
|
while [ "$#" -ge 1 ]; do echo " $1"; shift; done
|
|
echo
|
|
echo "See '${0##*/} -help' for usage"
|
|
echo
|
|
exit 1
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Input and outputs
|
|
unset dirList shellOutput shellFlavour
|
|
unset optDebug optEnvName optStrip optVerbose
|
|
|
|
# Parse options
|
|
while [ "$#" -gt 0 ]
|
|
do
|
|
case "$1" in
|
|
-h | -help*)
|
|
printHelp
|
|
;;
|
|
|
|
-env=*)
|
|
name="${1#*=}"
|
|
[ -n "$name" ] || die "Option '$1' missing an ENVNAME"
|
|
|
|
# Accept aliases
|
|
case "$name" in
|
|
(-path) name='PATH';;
|
|
(-lib)
|
|
case "$(uname -s 2>/dev/null)" in
|
|
(Darwin) name='DYLD_LIBRARY_PATH';;
|
|
(*) name='LD_LIBRARY_PATH';;
|
|
esac
|
|
;;
|
|
esac
|
|
optEnvName="$name" # Use for input evaluation
|
|
;;
|
|
|
|
-csh-path | -sh-path)
|
|
shellFlavour="$1"
|
|
name='PATH'
|
|
optEnvName="$name" # Use for input evaluation
|
|
shellOutput="$name" # Use for output
|
|
;;
|
|
|
|
-csh-lib | -sh-lib)
|
|
shellFlavour="$1"
|
|
case "$(uname -s 2>/dev/null)" in
|
|
(Darwin) name='DYLD_LIBRARY_PATH';;
|
|
(*) name='LD_LIBRARY_PATH';;
|
|
esac
|
|
optEnvName="$name" # Use for input evaluation
|
|
shellOutput="$name" # Use for output
|
|
;;
|
|
|
|
-csh=* | -sh=* | -csh-env=* | -sh-env=*)
|
|
shellFlavour="$1"
|
|
name="${1#*=}"
|
|
[ -n "$name" ] || die "Option '$1' missing an ENVNAME"
|
|
# Accept aliases
|
|
case "$name" in
|
|
(-path) name='PATH';;
|
|
(-lib)
|
|
case "$(uname -s 2>/dev/null)" in
|
|
(Darwin) name='DYLD_LIBRARY_PATH';;
|
|
(*) name='LD_LIBRARY_PATH';;
|
|
esac
|
|
;;
|
|
esac
|
|
shellOutput="$name" # Use for output
|
|
# Use for input evaluation
|
|
case "$1" in (*-env=*) optEnvName="$name";; esac
|
|
;;
|
|
|
|
-debug)
|
|
optDebug=true
|
|
;;
|
|
-strip)
|
|
optStrip=true
|
|
;;
|
|
-verbose)
|
|
optVerbose=true
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# Set the output prefix
|
|
# c-shell: setenv ENVNAME ...
|
|
# POSIX : ENVNAME=...
|
|
if [ -n "$shellOutput" ]
|
|
then
|
|
case "$shellFlavour" in
|
|
(-csh*) shellOutput="setenv ${shellOutput} " ;;
|
|
(*) shellOutput="${shellOutput}=" ;;
|
|
esac
|
|
fi
|
|
|
|
|
|
# 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
|
|
case "$filter" in
|
|
( / | /bin | /sbin | /lib | /lib64 | /opt \
|
|
| /usr | /usr/bin | /usr/sbin | /usr/lib | /usr/lib64 \
|
|
| /usr/local | /usr/local/bin | /usr/local/lib | /usr/local/lib64 )
|
|
# Do not filter out system directories
|
|
printDebug "skip>$filter<"
|
|
;;
|
|
|
|
(*)
|
|
if [ -n "$filter" ]
|
|
then
|
|
printDebug "remove>$filter<"
|
|
dirList=$(echo "$dirList:" | sed -e "s?${filter}[^:]*:??g")
|
|
fi
|
|
;;
|
|
esac
|
|
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
|
|
|
|
#------------------------------------------------------------------------------
|