[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bash script problem



On Wed, Aug 04, 2021 at 08:47:30PM -0700, Gary L. Roach wrote:
> Thanks for the help but I still have the problem of the if statement always
> being true. This time I enclosed the file so you can test it.

You didn't make the changes that I told you to make yesterday.  But
this has already been covered in detail, by myself and others.  Let's
move on to the bigger problems.

I can't tell what algorithm you're trying to use here, but it doesn't
look like it actually *works*.  Let's go back to the beginning.

You're writing a script that wants to check that all of the components
of a pathname actually exist, right?  So your input is something like

/usr/local/bin/youtube-dl

And you want to check whether /usr exists, and whether /usr/local exists,
and so on.

But what you've done is break the input into the following list of
words:

"" (the empty string)
usr
local
bin
youtube-dl

This isn't actually helpful.  You don't want to check wither "local"
is a directory.  You want to check whether "/usr/local" is a directory.

So, let's try to write a script that actually solves the problem.  We'll
start by checking whether the whole input as given to us is an existing
file system entry of some kind.  If it is, then we're already done --
all of the components exist, and there's nothing more to check.

If the input isn't an existing entry, then we'll strip off the last
component, check again, and so on until we reach a pathname that *does*
exist.

Here's a rough first approximation which does those things.  It may
not act precisely how you would like in all of the corner case inputs,
so some adjustments may be desirable.  But it's a good starting point.


#!/bin/bash

# If the input exists, we're done.
if [[ -e "$1" ]]; then
  echo "<$1> exists"
  exit 0
fi

# Otherwise, keep shortening it until we find something that exists,
# or we run out of pathnames to try.
f="$1"
echo "<$f> does not exist"
while [[ "$f" = */* ]]; do
  f="${f%/*}"
  if [[ -e "$f" ]]; then
    echo "<$f> exists"
    break
  else
    echo "<$f> does not exist"
  fi
done
exit 1


And, testing it:

unicorn:~$ ./foo /usr/local/bin
</usr/local/bin> exists
unicorn:~$ ./foo /usr/local/bin/rogue
</usr/local/bin/rogue> does not exist
</usr/local/bin> exists
unicorn:~$ ./foo /usr/local/sbin/rogue
</usr/local/sbin/rogue> does not exist
</usr/local/sbin> exists
unicorn:~$ ./foo /usr/local/xbin/rogue
</usr/local/xbin/rogue> does not exist
</usr/local/xbin> does not exist
</usr/local> exists
unicorn:~$ ./foo /urs/local/bin
</urs/local/bin> does not exist
</urs/local> does not exist
</urs> does not exist
<> does not exist
unicorn:~$ ./foo xyz
<xyz> does not exist

You will probably have questions about some of the syntax that I used.
Go ahead and ask them.


Reply to: