有一些代码应该在 bash 和 zsh 中工作。代码片段列出了所有目录,并按上次修改时间对它们进行排序。他很成功地解决了这个问题。列出的目录由相同的代码生成,仅包含符号a-zA-Z0-9-_,不包含空格。
mcve.sh:
#!/usr/bin/env bash
for i in $(ls -dt1 ./*/);
do
echo "${i}";
done
我使用外壳检查:
shellcheck mcve.sh
我得到以下结果:
In mcve.sh line 2:
for i in $(ls -dt1 ./*/);
^-- SC2045: Iterating over ls output is fragile. Use globs.
这种方法的“脆弱性”是什么?我该如何改进它?
明显的选项“使用 globs”是不合适的,因为 需要按时间排序。
问题在于它
ls主要设计用于以用户友好的格式显示文件列表。这包括它ls添加到文件名的任何标签和其他名称。ls -1不添加标签,但不摆脱“着色”。此外,操作ls可能会根据环境和操作系统的设置而有所不同,这将其从“通用解决方案”的类别转化为“可能工作”的类别。另外,不要忘记用户经常使用别名来为
ls.为了获得特定的文件列表并将其作为参数传递给其他命令,他们通常使用
find. 例如,要列出当前目录中的子目录,按 排序mtime,您可以这样做:“脆弱性”可能意味着处理可能出现在文件/目录名称中的特殊字符。例如空间:
而使用glob将给出正确的结果:
可以通过将嵌套命令括在引号中来避免此问题: