Patrickkasie
Patrickkasie

Reputation: 35

Bash script that checks for parts of current folderpath

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

Upvotes: 2

Views: 93

Answers (3)

pjh
pjh

Reputation: 8209

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).

Upvotes: 1

Diego Torres Milano
Diego Torres Milano

Reputation: 69396

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

Upvotes: 0

Fravadona
Fravadona

Reputation: 17290

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.

Upvotes: 1

Related Questions