我有以下 bash 脚本来创建一组目录、移动到该目录、执行一些操作(未显示)并返回到父目录:
#!/bin/bash
if [ -e 'dump' ]; then
rm -r dump
mkdir dump
D="dump/var"
else
mkdir dump
D="dump/var"
fi
for d in {1..24}
do
echo $D$d
mkdir $D$d/
cd $D$d
cd ..
done
执行此脚本时,结果是创建奇数目录,而偶数目录会抛出错误“没有这样的文件或目录”。如果我输入创建父目录的选项,如mkdir -p $D$d/
,则会产生嵌套目录dump/var1
、dump/dump/var2
、dump/dump/dump/var3
等等。
如果我删除目录更改,cd $D$d
和cd ..
,则脚本将执行而不会出错。如果我对目录使用绝对路径,如D="/path/to/directory/dump/var"
,则除了创建的第一个目录之外,其他所有目录都会显示“没有这样的文件或目录”。
外壳里发生了什么?
答案1
问题的核心:你的脚本cd
返回到 dump
,而不是dump/
的父级。
第一次迭代:
- 你从
dump
的父目录开始,其中dump/
存在 dump/var1
被建造- 你
cd
进入dump/var1
。 - 当
cd ..
发生时,您返回dump/
。当前工作目录是dump
,并且只有var1
那里,没有其他。
第二次迭代:
- 当你尝试时,
mkdir dump/var2/
你进入了dump/
,但只有var1
那里。dump/
ofdump/var2
是不存在的路径。当然会失败。因此出现错误消息,因此dump/dump/var2
使用mkdir -p
标志时会出现重复。 - 您的脚本仍然如此
cd ..
,因此在第 3 次迭代之前,当前工作目录从更改为dump/
的dump/
父目录。
对于第三次迭代:
- 您位于
dump/
的父目录中,该路径dump/
存在,因此mkdir dump/var3
不会失败。 cd dump/var3
那么cd ..
,发生什么了? ,现在的工作目录是什么?dump/
,上一级dump/var3
,您尝试执行mkdir dump/dump/var4
,但只有var1
,var3
没有dump
。mkdir
失败了,您cd ..
进入 的上一级dump/
,整个过程再次重复。
当您执行我们的脚本并在行set -x
后附加调试输出#!/bin/bash
或pwd
在脚本的每次迭代中执行第一个命令时,您可以清楚地看到这一点。
我建议修复脚本的方法是先通过cd
into dump/
,然后运行 for 循环。换句话说:
cd "$D"
for i in {1..24}
do
mkdir "$i"
cd "$i"
# do whatever you want inside "$i"
cd ..
done
除其他事项外,我建议使用[ -d "dump" ]
而不是-e
,因为这将帮助您确保存在的文件实际上是目录,尽管这可能需要额外的考虑。