1

Let $foo and $bar be two absolute directory names (output by realpath). I want to test if either is contained in the other one, at any depth, and execute commands accordingly.

I thought I'd use find, but its exit status doesn't tell whether something has been found or not. So I've come to:

if [ x$(find -H "$foo" -path "$bar" -printf y -quit) == xy \
    -o x$(find -H "$bar" -path "$foo" -printf y -quit) == xy ] ; then
    ...
fi

Is it correct? Is there something simpler?

Context: my home dir contains an encrypted folder (ecryptfs). I'm writing a script that will sync its argument to the cloud. I don't want the decrypted files to be synced, so I'll test whether the argument overlaps the encrypted folder to unmount the ecryptfs before syncing.

11
  • I don't understand. When you have 2 full (realpath) paths they can't contain eachother as they are absolute. Do you mean: Share a common parent folder?
    – Johan
    Jan 8, 2019 at 9:49
  • What are you looking for?: a tree being a sub-tree of another?; a tree being a sub-tree of another, but having a different name, because of sys-links?; a tree having a copy of part of another tree?; a tree containing a part of another tree because of bind mounts etc?; something else? Jan 8, 2019 at 10:06
  • Can't you just ignore the mounted directory with your script? How does the script sync the files?
    – Kusalananda
    Jan 8, 2019 at 10:20
  • @Johan I'm searching if either is contained in the other one (it could be foo under bar or bar under foo)
    – L. Levrel
    Jan 8, 2019 at 16:10
  • @ctrl-alt-delor a tree being a sub-tree of another
    – L. Levrel
    Jan 8, 2019 at 16:10

1 Answer 1

4

I'm not sure I fully understand the question and the context. But maybe this works:

foo="$(realpath "...")"
bar="$(realpath "...")"

if [[ $foo = $bar/* || $bar = $foo/* ]]; then
    echo "Overlap"
fi

Note that this won't work if one tree is sym-linked into the other.

7
  • If I understand the original question correct, $foo and $bar should already be results from realpath, so you could use $foo and $bar directly instead of $rd1 and $rd2
    – Bodo
    Jan 8, 2019 at 10:05
  • @Bodo You are right, updated.
    – Ralf
    Jan 8, 2019 at 10:14
  • Excellent! I didn't know that idiom. I think I need a / before the *, right? Also, man bash says there is no word splitting inside [[ ]], could I drop the double quotes there?
    – L. Levrel
    Jan 8, 2019 at 16:35
  • Good catch! Yes, the / is needed. The quotes are not needed. I always follow: if in doubt: quote. I'll update.
    – Ralf
    Jan 8, 2019 at 16:45
  • @Ralf thanks! I follow the same rule, but in an answer I think it's better to be as accurate as possible. I also did some tests about the quotes in foo="$(...)". The man is not very explicit about word splitting of the result of $(); I understand this result may be split according to the context, hence there is no word splitting here because variable assignments do not induce word splitting. Thanks again!
    – L. Levrel
    Jan 8, 2019 at 19:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .