Search code examples
bashcase-insensitive

In bash, can the file operator (-f) be case-insensitive?


I'm doing the following:

if [ -f $FILE ] ; then
    echo "File exists"
fi

But I want the -f to be case-insensitive. That is, if FILE is /etc/somefile, I want -f to recognize /Etc/SomeFile.

I can partially work around it with glob:

shopt -s nocaseglob
TARG='/etc/somefile'

MATCH=$TARG*    #assume it returns only one match
 
if [[ -f $MATCH ]] ; then
    echo "File exists" 
fi

but the case-insensitive globbing works only on the filename portion, not the full path. So it will not work if TARG is /Etc/somefile.

Is there any way to do this?


Solution

  • The problem is that your filesystem is case-sensitive. The filesystem provides only two relevant ways to get a file: either you specify an exact, case-sensitive filename and check for its existence that way, or you read all the files in a directory and then check if each one matches a pattern.

    In other words, it is very inefficient to check if a case-insensitive version of a file exists on a case-sensitive filesystem. The shell might do it for you, but internally it's reading all the directory's contents and checking each one against a pattern.

    Given all that, this works:

    if [[ -n $(find /etc -maxdepth 1 -iname passwd) ]]; then
      echo "Found";
    fi
    

    BUTunless you want to search everything from '/' on down, you must check component of the path individually. There is no way around this; you can't magically check a whole path for case-insensitive matches on a case-sensitive filesystem!