我正在尝试递归地处理镜像在第二个位置的目录和文件
我定义的函数是:
#!/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"
(但在这种特殊情况下,这会使代码的可读性较差,因此我保留了/
未加引号的部分)。