2

I'm attempting to recursively work on directories and files, that are mirrored at second location
The function I defined is:

#!/bin/bash
set -e
shopt -s nullglob
shopt -s dotglob
dom() {
    echo "Dirs:";
    for elem in "$1/*/"; do
        if test -d "$elem"; then
            echo is Dir # Is never called
        fi
        echo "$elem"; # intended to be dom "$elem" "$2"
    done;
    echo "Files:";
    for elem in "$1/*"; do # Same issues as above
        if test -f "$elem"; then
            echo "$elem is File" # is never called
        fi
        echo do stuff with "$elem" "$2/$elem";
    done;
}

dom "$2" "$1";

The Directory structure is:

- My Directory With Spaces/Subdir/...
- My Directory With Spaces/Subdir with Spaces/...
- My Directory With Spaces/Files...

- Other Dir/My Directory With Spaces/Subdir/...
- Other Dir/My Directory With Spaces/Subdir with Spaces/...
- Other Dir/My Directory With Spaces/Files...

The issue I'm running into is, that the glob does not correctly resolve or the for-loop iterates over the words in the pathname with spaces. With the code above I get:

$ ./script.sh Param1 My\ Directory\ With\ Spaces
Dirs:
My Directory With Spaces/*/
Files:
do stuff with My Directory With Spaces/* Param1/My Directory With Spaces/*

$ ./script.sh Param1 My\ Directory\ With\ Spaces/
Dirs:
My Directory With Spaces//*/
Files:
do stuff with My Directory With Spaces//* Param1/My Directory With Spaces//*

It should be

$ ./script.sh Param1 My\ Directory\ With\ Spaces
Dirs:
My Directory With Spaces/Subdir/
My Directory With Spaces/Subdir with Spaces/
Files:
do stuff with My Directory With Spaces/Files Param1/My Directory With Spaces/Files

$ ./script.sh Param1 My\ Directory\ With\ Spaces/
Dirs:
My Directory With Spaces/Subdir/
My Directory With Spaces/Subdir with Spaces/
Files:
do stuff with My Directory With Spaces/Files Param1/My Directory With Spaces/Files

Note, that the test is there to skip over the previously processed directories, but the debug echo is currently outside for debugging.

Effectively the question boils down to: Why doesn't the glob work as I expect it to?

I tried not quoting the $1/*/ or doing ${1// /\\ }/*/, but those did even weirder stuff. Changing the directory and back also isn't a viable option.

The following questions did not help:

1 Answer 1

5

The problem you have does not stem from the whitespace in the directory names, but (ironically) from the remedy you applied, which is correctly quoting your shell variables.

The quoting you applied is the correct way to address file and directory names with spaces, but inside quotes, glob expansion is disabled. That's why you get the literal * in your debug output (see e.g. this Q&A).

The solution in this case it to keep the globbing part outside of the quotes, as in

for elem in "$1/"*/; do ... ; done

and

for elem in "$1/"*; do ... ; done

Note that you can actually "interject" a glob in an unquoted section of an otherwise quoted variable reference, as in "$1/"*"/$2 and some static text" (but it would make the code less readable in this particular case, so I kept the / unquoted).

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .