Skip to content
Advertisement

Concatenating hardcoded directory and user-created text file adds root-level paths when it shouldn’t

I have written a script to allow a restricted user access to deleting files on a production webserver. However, to prevent fat-fingering issues leading to accidental filesystem deletion/problems, I have hard coded the base directory in a variable… But the final result is not properly creating the desired path from hard-coded directory + user paths if they have a * wildcard…

I have an Apache 2.4.6 server that caches web content for a user. They have a jailkit user to SSH into this box. As this is production, they are severely limited in their access, however, I would like to give them the ability to clear specific cache directories on their own terms. In order to prevent this from going horribly wrong, I have hard-coded the base cache directory into a script variable, so that no matter what, the script will only run against that path.

So far, this script works well to iterate through their desired cache clear paths… A user creates a .txt file with a /cachePath defined on each line, and the script will iterate through it and delete those paths. It works just fine for /path and /content/path2/ … But I cannot for the life of me get it working with wildcards (i.e. /path/, /content/path2/). There’s probably a sexier way to handle this than what I’ve done so far (currently have an if | else statement for handling * or /* not included in the script below), but I am getting all kinds of undesired results trying to handle a user-inputted * or /* on a custom path.

#!/bin/bash
#For this to work, a user must create a paths.txt file in their jailed home directory, based off the /mnt/var/www/html cache location. Each location (or file) must be on a new line, and start with a / 

    #User-created file with custom cache directories to delete
    file="/usr/jail/paths.txt"

    #Setting this variable to the contents of the user-created cache file
    pathToDelete=$(cat $file)

    #Hard-coded cache directory to try to prevent deleting anything important outside cache directory
    cacheDir="/mnt/var/www/html"

    #Let's delete cache
    if [ -f $file ];then
            echo "Deleting the following cache directories:"
            for paths in $pathToDelete
            do
                    echo $cacheDir"$paths" 
                    #rm command commented out until I get expected echo 
 output
                    #rm -rfv $cacheDir"$paths"
            done
            echo "Cache cleared successfully"
            mv $file "$file.`date +"%m%d%Y%H%M"`"
    else
            echo "Nothing to do"
    fi

I’ve tried double quotes, single quotes, no quotes, tried treating “pathToDelete” as an array, none of it is producing the desired output yet. For example, if paths.txt contains only “*”, the result is grabbing all directories under / and adding them to “cacheDir”?

/mnt/var/www/html/testing/backup
/mnt/var/www/html/testing/bin
/mnt/var/www/html/testing/boot
/mnt/var/www/html/testing/data
/mnt/var/www/html/testing/dev
/mnt/var/www/html/testing/etc
/mnt/var/www/html/testing/home
/mnt/var/www/html/testing/lib
/mnt/var/www/html/testing/lib64
...

If paths.txt is “./*” it’s adding files from the location of the script itself:

/mnt/var/www/html/testing./cacheClear.sh
/mnt/var/www/html/testing./paths.txt

Ultimately, what I’m looking for is this: if /mnt/var/www/html contains the following directories:

/content/
/content/path/
/content/path/file1.txt
/content/path/file2.txt
/content/path/subdir/
/path2/
/path2/fileA.txt
/path2/fileB.txt

Then a file containing /content/path/* should delete /content/path/file1.txt, file2.txt, and /subdir/, and preserve the /content/path/ directory.

If the paths.txt file contains

/content/path
/path2/*

Then /content/path directory and subfiles/directories should be deleted, and the files within /path2/ directory will as well… But right now, the script doesn’t see the concatenated $cacheDir + $paths as a real / expected location if it contains a * anywhere in it. Works ok without * symbols.

Advertisement

Answer

Got a version that works well enough for my purposes:

#!/bin/bash
file="/usr/jail/paths.txt"
pathToDelete=$(cat $file)
cacheDir="/mnt/var/www/html"

if [ -f $file ]; then
        if [ "$pathToDelete" == "*" ] || [ "$pathToDelete" == "/*" ]; then
                echo "Full Clear"
                rm -rfv /mnt/var/www/html/*
        else
                echo "Deleting the following cache directories:"
                for i in ${pathToDelete};
                do
                        echo ${cacheDir}${i}
                        rm -rfv ${cacheDir}${i}
                done
                echo "Cache cleared successfully"
        fi
fi
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement