尝试将目录名称传递给函数时出现“是目录”错误

尝试将目录名称传递给函数时出现“是目录”错误

在我的 bash 脚本中,我使用 find 通过通配符获取文件夹名称:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
  stuff=doStuff ${i}
done

doStuff() {
  echo ${1}
  return ${1}'/hello';
}

问题是,当我这样做时,我收到以下错误(假设 ${i} 对应于“home/me/my_directory”):

line 111: '/home/me/my_directory': is a directory. 

(第 111 行是带有“doStuff”的行)

我尝试这样做,但无济于事:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
  stuff=doStuff "${i}"
done

显然这是因为程序正在尝试执行该目录,但我只想将其作为我可以操作的字符串。

答案1

引号和命令替换是您的问题。

您遇到的具体问题是因为 shell 正在尝试运行/home/me/my_directory使用环境变量调用的命令stuff=doStuff
你真正想要的(如果我解释正确的话)是以doStuff的值$i作为参数运行,将输出分配给变量stuff。执行此操作的方法是将命令包装在$().例如:

stuff="$(doStuff "$i")"

请注意我如何在所有内容周围加上引号。这是为了防止 shell 对您不希望它进行分词的内容进行分词(它将/foo/bar baz把的单个参数变成/foo/barand 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

在尝试使用函数之前,您必须先放置函数定义。 Shell 不像编译程序那样进行解析,后者会多次遍历文件。这是自上而下的。
我还进行了修改,doStuff将其发送echo到 STDERR,它将显示在终端上,然后将其printf发送到 STDOUT,并将其捕获到变量中stuff

请注意,如果您的任何目录包含换行符,这仍然会出现问题。然而,这是 shell 的限制。文件路径唯一不能包含的字符是 NULL 字符 ( \0)。然而 bash 和其他 shell 不能在字符串中存储 NULL 字符(不是全部,但很多。我知道 zsh 可以),所以你不能将它用作分隔符。

答案2

这是一项很好的努力,但它表明您正在尝试bash像编程语言一样进行编写,而实际上它是一种简单的脚本语言。你的构造的问题stuff=doStuff arg在于,bash它并不意味着你认为它意味着什么。 To bash,stuff=doStuff是变量赋值,并且arg是命令。我建议您阅读以下两个链接:

与您所拥有的类似的工作版本将是

doStuff () {
    echo "$1/hello"
}

stuff=$(doStuff "$i")

答案3

给出错误的行并没有按照您的想法进行操作:

它首先将环境变量 stuff 设置为字符串“doStuff”,然后尝试将 ${i} 作为命令执行。由于 ${i} 是一个目录,因此失败并显示给定的错误消息。

相关内容