Monday, April 27, 2009

Parsing env variable PATH in bash


Requirement: Check for the existence of the directories mentioned in PATH env variable.

The bash script:

#!/bin/sh
IFS=:

read dirs <<END
$PATH
END

for dir in $dirs
do
[ ! -e "$dir" ] && echo "$dir not exist" \
|| echo "$dir exist"
done

Executing the above bash script:

$ ./check-PATH.sh
/usr/local/bin exist
/usr/bin exist
/bin exist
/usr/X11R6/bin exist
/cygdrive/c/WINDOWS/system32 exist
/cygdrive/c/WINDOWS exist
/usr/bin exist
/usr/lib/sanity not exist


Read more about Bash IFS (Internal Field Separator) from tldp.org

1 comment:

Anirudh said...

> read dirs < $PATH
> END

This is not needed actually;
The following would work just as well

for dir in $PATH; do
...
done

Now, since $PATH is unquoted, so
we need to guard against any filename expansion, if an element in PATH were to contain chars like * ? etc.
To pre-empt such an eventuality,
we disable filename expansion, via,

set -f


> for dir in $dirs
> do
> [ ! -e "$dir" ] && echo > "$dir not exist" \
> || echo "$dir exist"
> done

There are 2 things in the above for-do loop, viz.,
i ) the check for $dir should be extended.
ii ) the && || construct should be rewritten to make it logically tighter, for example, if for some reason, the first echo failed, then we would see the second echo being executed. Of course this shouldnt happen since they are mutually exclusive.

[ ! -e "$dir" ] && { >&2 echo "'$dir' does not exist."; :; } || { \
[ ! -d "$dir" ] && { >&2 echo "'$dir' is not a dir."; :; } || { \
[ ! -r "$dir" ] && { >&2 echo "'$dir' is not readable."; :; } || { \
[ -w "$dir" ] && { >&2 echo "'$dir' is writable by you."; :; } || { \
echo "'$dir' is safe for your use."; }; }; }; }

© Jadu Saikia www.UNIXCL.com