bashmkdirdirname

Bash. Recursive directory creation permission check


I want in Bash to create recursively a dir checking first if the user has permissions. I know that mkdir -p will create all the subdirs but the point is that I want to check if the user is able to do it before doing it.

In my program, a path is given by the user to create the dir. Let's suppose the var givenpath with value /root/newdir/anothernewone. User root is going to be able to create it but any other normal user is not going to be able to create it. I want to check if the user is able to do it. My non-working approach:

#!/bin/bash

givenpath="/root/newdir/" # This works
#givenpath="/root/newdir/anothernewone/" # This is not working

if [ -d $(dirname "${givenpath}") ]; then
    if [ ! -w $(dirname "${givenpath}") ]; then
        echo "Error, You don't have write permissions"
    else
        echo "Yeah, there are permissions"
    fi
else
    echo "Error, base dir to create subdirs is not existing"
fi

This is not working completely. With givenpath /root/newdir it will work because basedir is /root/ and it's correctly checked for both users, but if more subdirs are given like /root/newdir/anothernewone it will fail because basedir is /root/newdir/ so the basedir is not existing yet and it will fail for both users.

The point is to be able to create the dirs checking first if is possible. Maybe one solution could be do a recursive check of every dir starting on the given first level until reach a non-existing dir checking if there are write permission on the last existing...

Another very very dirty approach I'm thinking in, could be to launch the mkdir -p command and check the exit code. If it's different than 0, everything clear, no permissions... and if it's 0 ok, there are permissions but then I should delete the created directories because what I want is to check without creating the dirs.

but I don't know how to do it. Any help? Thanks.


Solution

  • I did a recursive function... still on testing but maybe it could be a solution. Please, if somebody can contribute to improve it, it is welcome:

    #!/bin/bash
    
    #givenpath="/root/" #root can write, user not
    givenpath="/root/newdir/anothernewone/" #root can write, user not
    #givenpath="/home/user/newdir" #both user and root can write
    
    function dir_permission_check() {
    
        if [ -w "${1}" ]; then
            return 0
        else
            basedir=$(dirname "${1}")
            if [ "${basedir}" != "/" ]; then
                if dir_permission_check "${basedir}"; then
                    return 0
                else
                    return 1
                fi
            elif [ -w "${basedir}" ]; then
                return 0
            else
                return 1
            fi
       fi
    }
    
    dir_permission_check "${givenpath}"
    echo $?
    

    If an exit code of 0 is returned, there is permissions to write, otherwise the user has not permissions. Any opinion about this function I did? maybe it is not too much elegant solution but it seems it's working.

    EDIT

    It seems the function is working ok. Here is one improved and more clean:

    #!/bin/bash
    
    #givenpath="/root/" #root can write, user not
    givenpath="/root/newdir/anothernewone/" #root can write, user not
    #givenpath="/home/user/newdir" #both user and root can write
    
    function dir_permission_check() {
    
        if [ -e "${1}" ]; then
            if [ -d "${1}" ] && [ -w "${1}" ] && [ -x "${1}" ]; then
                return 0
            else
                return 1
            fi
        else
            dir_permission_check "$(dirname "${1}")"
            return $?
        fi
    }