以下代码旨在查找~/Downloads
. 我用. ./script.sh
. 即使用户提交的名称不完整,它也会找到它们。
#!/usr/bin/bash
echo -e "\nGive me the name of a nonexitent directory and I will look for it in ~/Downloads?\n"
read word
TOGOs=("$(find ~/Downloads -maxdepth 1 -iname "*$word*" -type d -execdir echo {} + | sed 's;./;/home/smith/Downloads/;g')"
"")
for togo in ${TOGOs[@]}
do
if [[ $togo != "" ]]; then
echo $togo
export togo && cd $togo && return 0
else
echo "Haven't found it in ~/Downloads ." && cd ~/Downloads #This line does not work
fi
done
该if
部分按预期工作 - 当我给它一个名称/子目录名称的一部分时~/Downloads/
,但是else
当我给它一个不存在的目录时,该块的部分永远不会被执行。else
当我摆脱循环时,我可以执行该部分,如下所示:
#!/usr/bin/bash
echo -e "\nGive me the name of a nonexitent directory and I will look for it in ~/Downloads?\n"
read word
TOGO=$(find ~/Downloads -maxdepth 1 -iname "*$word*" -type d -execdir echo {} + | sed 's;./;/home/smith/Downloads/;g')
if [[ $TOGO != "" ]]; then
echo $TOGO
export TOGO
cd $TOGO && return 0
else
echo "Haven't found it in ~/Downloads." && cd ~/Downloads
fi
为什么else
当我摆脱循环时手臂会被执行?如何在保留循环的同时执行我的代码?
${TOGOs[@]}
表示获取数组的元素,在空格处将它们分解为单独的单词(假设为 defaultIFS
),并将每个单词解释为 glob 模式。它与$var
标量变量相同,只是它依次列出所有元素。如果数组中有一个空元素,拆分步骤会将其转换为 0 个单词的列表,因此它被有效地删除。
与往常一样:在变量和命令替换周围使用双引号,除非您知道需要将它们排除在外。要列出数组的元素,正确的语法是
"${TOGOs[@]}"
. 数组访问“胜过”双引号:数组的每个元素都放在一个单独的单词中。但是,使用正确的数组列表语法对您没有帮助,因为您构造数组的方式没有意义。您将整个输出
find
放入单个数组元素中。您无法解析find
这种方式的输出:无法区分作为文件名一部分的换行符和find
用于区分文件名的换行符。而不是解析 的输出,而是
find
在 bash 中进行处理,或者使用find -exec …
.shopt -s globstar
如果您需要,Bash 具有递归通配符(由 启用),但是由于您正在使用它,find -maxdepth 1
因此您实际上不需要它,并且实际上并find
没有做任何有用的事情。