for 循环遍历带有空格的目录 glob 将不起作用

for 循环遍历带有空格的目录 glob 将不起作用

我正在尝试递归地处理镜像在第二个位置的目录和文件
我定义的函数是:

#!/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";

目录结构为:

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

我遇到的问题是,glob 无法正确解析,或者 -loopfor迭代路径名中带有空格的单词。通过上面的代码我得到:

$ ./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//*

它应该是

$ ./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

请注意,测试是为了跳过之前处理的目录,但调试回显当前位于外部进行调试。

实际上,问题归结为:为什么 glob 没有按照我的预期工作?

我尝试不引用$1/*/或做${1// /\\ }/*/,但那些做了更奇怪的事情。更改目录并返回也不是一个可行的选择。

以下问题没有帮助:

答案1

您遇到的问题并非源于目录名称中的空格,而是(具有讽刺意味的是)源于您应用的补救措施,即正确引用 shell 变量。

您应用的引号是用空格寻址文件和目录名称的正确方法,但在引号内,全局扩展被禁用。这就是为什么你*在调试输出中得到文字(参见例如本次问答)。

在这种情况下的解决方案是保留通配部分外部的引号,如

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

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

请注意,您实际上可以在否则引用的变量引用的未加引号的部分中“插入”一个 glob,如下所示"$1/"*"/$2 and some static text"(但在这种特殊情况下,这会使代码的可读性较差,因此我保留了/未加引号的部分)。

相关内容