use*_*763 6 bash find shell-script
在我的 bash 脚本中,我使用 find 通过通配符获取文件夹名称:
for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
stuff=doStuff ${i}
done
doStuff() {
echo ${1}
return ${1}'/hello';
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我这样做时,我收到以下错误(假设 ${i} 对应于“home/me/my_directory”):
line 111: '/home/me/my_directory': is a directory.
Run Code Online (Sandbox Code Playgroud)
(第 111 行是带有 'doStuff' 的行)
我试过这样做,但无济于事:
for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
stuff=doStuff "${i}"
done
Run Code Online (Sandbox Code Playgroud)
显然这是因为程序正在尝试执行该目录,但我只是希望它作为一个我可以操作的字符串。
引号和命令替换是您的问题。
您遇到的具体问题是因为 shell 正在尝试运行/home/me/my_directory
使用环境变量调用的命令stuff=doStuff
。
您真正想要的(如果我的解释正确的话)是以doStuff
的值$i
作为参数运行,将输出分配给变量stuff
。这样做的方法是将您的命令包装在$()
. 例如:
stuff="$(doStuff "$i")"
Run Code Online (Sandbox Code Playgroud)
请注意我如何在所有内容周围加上引号。这是为了防止 shell 对您不希望它进行分词的内容进行分词(它会将 的单个参数/foo/bar baz
转换为/foo/bar
and baz
)。
此外,您的函数的输出是用作返回值的内容,而不是return
.
由于您应该使用更多引号,因此您还应该将它们添加到其他所有内容中。这是您的脚本的完整版本:
doStuff() {
echo "${1}" >&2
printf '%s/hello' "$1";
}
IFS=$'\n'
for i in $(find "${directory}" -mindepth 1 -type d -name "${wildcard}");
do
stuff="$(doStuff "${i}")"
done
Run Code Online (Sandbox Code Playgroud)
在尝试使用它之前,您必须放置函数定义。Shell 不像编译程序那样被解析,它会多次遍历文件。它是自上而下的。
我还修改doStuff
了将 发送echo
到 STDERR,它将在终端上显示,然后printf
发送到 STDOUT,在那里它将被捕获到变量中stuff
。
请注意,如果您的任何目录包含换行符,这仍然会出现问题。但是,这是外壳的限制。文件路径不能包含的唯一字符是 NULL 字符 ( \0
)。但是 bash 和其他 shell 不能在字符串中存储 NULL 字符(不是全部,而是很多。我知道 zsh 可以),因此您不能将其用作分隔符。