5

I have the function:

function vacatetmp () {
    echo "Vacating TMP folder ${1}...."
    for i in "$1"/*; do
        if [ -f "$i" ]; then
            caseit "$i"
          elif [ -d "$i" ]; then
               vacatetmp "$i"
        fi
    done
}

It works fine if the content inside the target folder is static - i.e no change to the files while the function is invoked. But the problem is that another function reference in this code as caseit, can and does add new files to the target folder. Since the target folder list "$1"/* is an array that is listed when for is invoked, the new files created by caseit are NOT added to that array, and thus are not taken care of by the recursion in function vacatetmp. Can someone please help by suggesting a way to deal with this issue? I would like this function to also take care of new files added by caseit function.

For clarity sakes, caseit function looks up a mime type of the $i file passed to it by vacatetmp and unzips the files into the target folder "$1" - since archives can contain multiple directory hierarchies I have no way of knowing how deep the files will be created, which is the reason for using recursive function.

  • you probably instead want some sort of inode change notify thing (e.g. entr) instead of trying to bend glob(3) to do something unnatural – thrig Feb 22 '18 at 17:06
  • I think what I am asking can be solved by recursively going over the array that contains the list of files under directory structure, and using shift to advance within it while using =+(newfilename) to add new element at the end of array if "caseit" adds a new element. I just can't wrap my head around on how to write it - don't have much experience with arrays and intricacies of handling them in bash. – sheikhness Feb 25 '18 at 14:59
1

Iterate over the files first, open them, then iterate over the directories.

for i in "$1/*"; do [[ -f "$i" ]] && caseit "$i"; done; 
for i in "$1/*"; do [[ -d "$i" ]] && vacatetmp "$i"; done

It would be more thorough to also call vacatetmp() from within caseit(), at it's end. But I doubt that is needed, and would lead to less maintainable code.

  • I think that does it... I since have rewritten my scripts to take a different approach to checking newly added files - ( I flat out dir structure first, then go over the files and remove them after they are taken care of, then go over the thing with flat out {n} times until no files are left). I won't mark it as answer because I cannot properly test the answer in my particular case - but I think the above solution solves it rather elegantly, thanks! – sheikhness Jun 12 '18 at 10:16
0

Here's some idea for you. It's not been tested though.

The idea is to separate the newly unzipped files and directories for each single source file in its own temporary folder. This is recursively repeated, and when the recursion comes back from the depths, the files and dirs are moved to their proper destination, and the temporary directory is removed.

function vacatetmp () {
    echo "Vacating TMP folder ${1}...."
    # You need a prefix for the new auxiliary temporary folders.
    prefix=SomeGoodPrefix
    for i in "$1"/*; do
        if [ -f "$i" ]; then
            # From your explanation:
            # "Look up the mime type of "$i" and unzip the files into "$1"."
            # Now, before you mix the new files and dirs with the old ones,
            # unzip them to a special new directory with the prefix and the file name
            # so that they're not mixed with the files and directories already present in "$1".
            mkdir "$1"/"${prefix}""$i" &&
            # How do you pass the target directory to "caseit"?
            # However you do, pass it the temporary folder.
            caseit "$i" "$1"/"${prefix}""$i" &&
            # Now the new unzipped files and folders are in "$1"/"${prefix}""$i", so
            # vacatetmp the auxiliary prefixed directory: 
            vacatetmp "$1"/"${prefix}""$i" &&
            # and after you've finished with vacatetmp-ing that directory,
            # move the contents of it to "$1".           
            mv "$1"/"${prefix}""$i"/* "$1" &&
            # And finally remove the prefixed directory.
            rmdir "$1"/"${prefix}""$1"
            # This file is done. Recursively.
        elif [ -d "$i" ]; then
            vacatetmp "$i"
        fi
    done
}

Let me know if I blundered somewhere. It's not been tested, as I've warned before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.