在子shell中运行的命令的stdout没有被" $()"捕获。

时间:2014-12-01 16:38:35

标签: bash shell

因此,出于某种原因,我编写了这个脚本来获取某个sbt项目的程序化描述。

#!/bin/bash
project_name="$(sbt project | tail -n1 | cut -d' ' -f 2- | sed 's!\s*(in build.*)!!')"
project_version="$(sbt version | tail -n1 | cut -d' ' -f 2-)"

echo $project_name
echo $project_version

echo "find . -name ${project_name}*.jar"    
echo "Find: $(find . -name ${project_name}*.jar)"

然而,最终的回声(在find中运行$())并没有给我任何输出,尽管表面上运行的命令与上面打印的相同。

我也使用bash -ex运行上述脚本,所以:

  • 我知道打印的find ...命令有效,即它正在寻找的文件存在
  • 我知道在${project_name}
  • 内正确扩展了"$()"
  • 我知道echo Echo: "$(echo ${project_name})"有效
  • 使用-ex,最终查找将打印为++ find . -name 'my-test-app*.jar'

但是最后的echo "Find: $(find . -name ${project_name}*.jar)"永远不会返回任何东西。它只打印Find:

2 个答案:

答案 0 :(得分:3)

您可能需要引用,因为否则您的find命令就像find . something*.jar一样,在没有适当控制的情况下会扩展:

echo "Find: $(find . -name "${project_name}*.jar")"
                           ^                    ^

我做了一些测试,它对我来说很好,但没有这些引用。

测试

$ touch a1.jar
$ touch a123.jar

没有引号:

$ find . -name a*jar
find: paths must precede expression: a1.jar
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

引用:

$ find . -name "a*jar"
./a123.jar
./a1.jar

答案 1 :(得分:0)

find的选项-name需要一种模式。但是在你的代码中,在发现find之前,*由shell扩展。

所以你有两个选择:

  • 使用引号:echo "Find: $(find . -name "${project_name}*.jar")"
  • 或逃避*echo "Find: $(find . -name ${project_name}\*.jar")