0

I'm working on the bash script that iterates over the list of files. I need to compare the paths to this files with the array containing the restricted paths.

Inside the for loop I get a path to a file like this:

dname="$(dirname "$i")";

This returns me a relative path like path/to/file

The list of restricted paths is stored in the array:

restricted=(
   path/to/file
   another/path/to/file
);

Then I'm trying to compare the paths:

if [[ "${restricted[*]}" = "$dname" ]]; then

//do some things

fi

However the comparison does not seem to work.

Could you please advise how to solve the issue?

Thank you.

Sray
  • 101
  • 3

3 Answers3

1

You need to iterate over the elements of the array something like

for i in "${restricted[@]}"
do
    if [ "$i" == "$ddame" ] ; then
        echo "Found"
    fi
done
user9517
  • 115,471
  • 20
  • 215
  • 297
  • Is there any way NOT to iterate over the array? Why doesn't my code work though it works for the array of restricted files: if [[ "${fnames[*]}" =~ "$filename" ]]; then ... - this works. – Sray May 01 '14 at 12:30
  • I've no idea, this is what I would do. – user9517 May 01 '14 at 12:35
  • '==' with [ is incorrect, the operator is =. Some shells accept it, and others don't, meaning the comparison silently fails. – Chris Rees Mar 03 '21 at 09:27
0

Iain's answer is the official and best one. When I write scripts, that's what I use. However, here is an alternative. It's not wrong with a capital "W", but I'd still wouldn't really recommend it.

if $(echo "${restricted[@]}" | grep -sw "${dname}") ; then
      echo "found"
 else
      echo "not found"
fi

This echos your array, pipes the output to grep, which will only match a whole word (-w) and will provide no output (-s), instead indicating via the exit code that there was/was not a match. That exit code is what you use as the test for the if statement.

Note that this method has the same glaring issue as your =~ example you posted for the file name. It will match on directories that contain your string as a subcomponent. eg: /path/to/file/subfolder and /usr/local/path/to/file will both match. (The slashes count as non-word delimiters to grep's -w) The partial match selector of =~ you're using for your file names will have the same issue.

user9517
  • 115,471
  • 20
  • 215
  • 297
Christopher Karel
  • 6,582
  • 1
  • 28
  • 34
0

You can't directly compare an array with a variable; it expands to:

[ "one two three" = "two" ]

Looking at that, I'm sure you can see the problem!

Perhaps:

case "${restricted[*]}" in
$ddname|* $ddname|* $ddname *|$ddname *)
    # do something
    ;;
esac

Untested, you may need quotes on the testing line.

Otherwise, iteration is the only method.

Chris Rees
  • 275
  • 1
  • 7