tags:

views:

232

answers:

4

With /bin/bash, how would I detect if a user has a specific directory in their $PATH variable?

For example

if [ -p "$HOME/bin" ]; then
  echo "Your path is missing ~/bin, you might want to add it."
else
  echo "Your path is correctly set"
fi
+4  A: 
echo "$PATH" | grep -q "\(^\|:\)$HOME/bin\(:\|\$\)"
JasonWoof
+2  A: 

Something really simple and naive:

echo "$PATH"|grep -q whatever && echo "found it"

Where whatever is what you are searching for. Instead of && you can put $? into a variable or use a proper if statement.

Limitations include:

  • The above will match substrings of larger paths (try matching on "bin" and it will probably find it, despite the fact that "bin" isn't in your path, /bin and /usr/bin are)
  • The above won't automatically expand shortcuts like ~

Or using a perl one-liner:

perl -e 'exit(!(grep(m{^/usr/bin$},split(":", $ENV{PATH}))) > 0)' && echo "found it"

That still has the limitation that it won't do any shell expansions, but it doesn't fail if a substring matches. (The above matches "/usr/bin", in case that wasn't clear).

Adam Batkin
Matching to beginning/end of line and colons as in JasonWoof's answer takes care of your substring match limitation. Tilde expansion is not a common issue, since most people allow it to be expanded when assigned (e.g. `PATH="~/bin:$PATH"`) but can be taken care of with a substitution if necessary.
Jefromi
+3  A: 

Using grep is overkill, and can cause trouble if you're searching for anything that happens to include RE metacharacters. This problem can be solved perfectly well with bash's builtin [[ command:

if [[ ":$PATH:" == *":$HOME/bin:"* ]]; then
...

Note that adding colons before both the expansion of $PATH and the path to search for solves the substring match issue; double-quoting the path avoids trouble with metacharacters.

Gordon Davisson
If `$HOME/bin` is at the beginning or end of `$PATH`, then there's not likely to be a colon at each end.
Dennis Williamson
I'm not sure I'm understanding your objection. For example, if $PATH is /usr/bin:/bin:/usr/sbin:/sbin:/home/fred/bin, then ":/usr/bin:/bin:/usr/sbin:/sbin:/home/fred/bin:" will match *":/home/fred/bin:"* just fine.
Gordon Davisson
You're right. I had failed to see the role of the colons around "$PATH". Sorry.
Dennis Williamson
A: 

Here's how to do it without grep:

if [[ $PATH == ?(*:)$HOME/bin?(:*) ]]

The key here is to make the colons and wildcards optional using the ?() construct. There shouldn't be any problem with metacharacters in this form, but if you want to include quotes this is where they go:

if [[ "$PATH" == ?(*:)"$HOME/bin"?(:*) ]]

This is another way to do it using the match operator (=~) so the syntax is more like grep's:

if [[ "$PATH" =~ (^|:)"${HOME}/bin"(:|$) ]]
Dennis Williamson