Ok so I got this:


The above gets me each path in a simplified manner, and formats it nicely into a variable. Now how do I check each line for existence, and state that for each line in combination with an echo (I think I would use echo.)?

I know it probably involves a for or while loop, but I'm not sure how to do this.

BASH only answers please.

while read -d: dir
    [ -d "$dir" ] || echo "Missing: $dir"
done <<<"${PATH%:}:"

read -d: dir reads input into variable dir, breaking the input at :.

[ -d "$dir" ] tests for the existence of the directory

|| only executes the statement that follows if the preceding statement returned false.

<<<"${PATH%:}:" provides input to the loop using a here-string. The form "${PATH%:}:" makes sure that one : follows the PATH string. This is done in two steps. The first uses suffix removal, ${PATH%:}, to remove a trailing : from the PATH if there is one. Secondly, one colon is added.

| improve this answer | |
  • With bash 4.2.8 the last path in $PATH is ignored. – Cyrus Nov 18 '15 at 6:29
  • 1
    @Cyrus Thanks. I believe the updated answer fixes that. – John1024 Nov 18 '15 at 18:01

This combines the best parts of the three answers1 existing at the time of this posting (sort answers by “oldest” if you want to see which ones those are) and adds a slightly different way of doing what John1024 is doing:

IFS=: read -a path_components <<< "$PATH"
for dir in "${path_components[@]}"
    printf "%s\t-> " "$dir"
    if [ -d "$dir" ]
        echo "Exists."
        echo "Missing!!!!"

IFS=: does essentially the same thing as John’s read -d:; it breaks the input at : (and not at space or tab); so, like John’s answer, this handles directories with whitespace in their names correctly.  read -a path_components reads the input into an array; "${path_components[@]" expands to a list of the members of the array.  Note that echo "$dir" can be dangerous if $dir begins with a - or contains a \.  (Admittedly, these with be rare for directory names in $PATH.)  printf "$dir" can be dangerous if $dir contains a %.
1 one of which was deleted as I composed this answer


You can try this way out also:


arr=$(echo $PATH | tr ":" "\n")

for x in $arr
    echo -n "$x"
     if [ -d "$x" ];then
        echo " -> Exists"
         echo -e " -> \e[31mMissing!!!!\e[0m"

With arr=$(echo $PATH | tr ":" "\n") you split the directories in a variable and the echo -e add color red to the display to draw attention to.

The output will be like follows:

/usr/lib/qt-3.3/bin -> Exists

/usr/local/sbin -> Exists

/usr/local/bin -> Exists

/sbin -> Exists

/bin -> Exists

/usr/sbin -> Exists

/usr/bin -> Exists

/root/bin -> Missing!!!

| improve this answer | |
  • 2
    This will fail if $PATH contains space(s) (or tabs).  This is unusual in Unix/Linux per se, but common in Cygwin, where the Cygwin/Unix $PATH incorporates the Windows %PATH% and so will include directories like /cygdrive/c/Program Files/Microsoft Games. – G-Man Says 'Reinstate Monica' Nov 18 '15 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.