2

Clean and simple: how do I check with bash for certain parts of the folder I'm currently in?

#!/usr/bin/sh
CURRENTFOLDER=$(pwd)
echo "${CURRENTFOLDER}"
CHECKFOLDER="/home/*/domains/*/public_html"
if [ $CURRENTFOLDER ! $CHECKFOLDER ]
then
    echo "Current folder is not /home/user/domains/domain.com/public_html"
    exit
fi

User and domain are variable, I don't need to know them for this checkup, just the 3 pre-defined folders in the variable CHECKFOLDER

Donald Duck
  • 8,409
  • 22
  • 75
  • 99

3 Answers3

1

There's a problem with this approach.
For example in bash the following expression evaluates to true:

[[ /www/user/domains/local/public_html == /www/*/public_html ]] 

It is more accurate to use a bash regex:

[[ /www/user/domains/local/public_html =~ ^/www/[^/]+/public_html$ ]]

So your code would become:

#!/bin/bash

current_folder=$PWD
check_folder='^/home/[^/]+/domains/[^/]+/public_html$'

if ! [[ $current_folder =~ $check_folder ]]
then
    echo "Current folder is not /home/user/domains/domain.com/public_html"
    exit
fi

BTW, the shebang needs to be a bash, not sh. And it's kind of dangerous to capitalize your variables.

Fravadona
  • 13,917
  • 1
  • 23
  • 35
  • This approach can fail if any of the paths contain symlinks. – pjh May 17 '22 at 19:33
  • I'm not sure to understand what symlinks have to do with verifying that a string matches a pattern. Do you refer to `$PWD`? – Fravadona May 17 '22 at 19:45
  • For example, running `cd /tmp; ln -s /home/auser/domains/adomain/public_html public_html; cd public_html` changes to a valid directory but `PWD` has the value `/tmp/public_html`. – pjh May 17 '22 at 21:15
  • I understand your point, but what would happen if the script have to `source ../lib/env.sh`? Wouldn't that be dangerous to allow any path as long as it refers to the same inode? – Fravadona May 17 '22 at 21:16
1

Try this (almost) Shellcheck-clean code:

#! /usr/bin/sh

curr_phpath=''
for phpath in /home/*/domains/*/public_html/; do
    if [ "$phpath" -ef . ]; then
        curr_phpath=$phpath
        break
    fi
done

if [ -z "$curr_phpath" ]; then
    echo "Current folder is not /home/user/domains/domain.com/public_html" >&2
    exit 1
fi
  • Because of aliasing mechanisms (e.g. symbolic links, bind mounts) it is very difficult in general to determine if two paths reference the same file or directory by comparing them textually. See How to check if two paths are equal in Bash? for more information. This solution uses a more reliable mechanism to determine if the current directory is one of the valid ones.
  • Since the shebang line references sh instead of bash, the code avoids Bashisms. It's been tested with both bash and dash (probably the most common non-Bash sh).
  • See Correct Bash and shell script variable capitalization for an explanation of why the code does not use ALL_UPPERCASE variable names.
  • The [ "$phpath" -ef . ] test is true if the .../public_html path being checked is the same directory as the current directory. The -ef operator is not in POSIX so it is not guaranteed to be supported by an sh shell, and Shellcheck (correctly) warns about it. However, it is supported in both bash and dash, and sh is usually one of those (on Linux at least).
pjh
  • 6,388
  • 2
  • 16
  • 17
0

You can save a step just by changing to the directory instead of checking.

Check your glob matches only one file first.

Then, cd to check it's a dir.

#! /bin/bash

IFS="$(printf '\n\t')"
files=( $(compgen -G '/home/*/domains/*/public_html') )
if [[ "${#files[@]}" != 1 ]]
then
    printf 'Multiple matches\n' >&2
    exit 1
fi
if ! cd "${files[0]}" 
then
   printf 'Cannot chdir\n'
   exit 1
fi
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134