0

我的目标 --> 命令中的文件列表必须逐行读取并用作另一个命令的一部分。

说明 --> linux中的一个命令返回

archive/Crow.java
archive/Kaka.java
mypmdhook.sh

它存储在changed_files变量中。我使用以下 while 循环逐行读取文件并将其用作 pmd 命令的一部分

while read each_file
do
        echo "Inside Loop --  $each_file"
done<$changed_files

我是编写 shell 脚本的新手,但我的假设是这些行会在循环中分开并在每次迭代中打印,但我得到以下错误 -

mypmdhook.sh: 7: mypmdhook.sh: cannot open archive/Crow.java
archive/Kaka.java
mypmdhook.sh: No such file

你能告诉我如何将值作为字符串而不是作为打开的文件获取。顺便说一句,该文件确实存在,这让我感到更加困惑。(后来在命令中使用它)。我会对任何有助于我理解和解决此问题的答案感到满意。

4

3 回答 3

1

由于您将数据存储在变量中,因此请使用“此处字符串”而不是文件重定向:

changed_files="archive/Crow.java
archive/Kaka.java
mypmdhook.sh"
while read each_file
do
        echo "Inside Loop --  $each_file"
done <<< "$changed_files"
Inside Loop --  archive/Crow.java
Inside Loop --  archive/Kaka.java
Inside Loop --  mypmdhook.sh

"$changed_files"为了保留换行符,引用非常重要,因此 while-read 循环按您的预期工作。经验法则:总是引用变量,除非您确切知道为什么要去掉引号。

于 2014-09-24T17:45:58.973 回答
0

而不是while像这样将命令的输出存储在变量使用循环中:

mycommand | while read -r each_file; do echo "Inside Loop -- $each_file"; done

如果您使用 BASH,您可以使用process substitution

while read -r each_file; do echo "Inside Loop -- $each_file"; done < <(mycommand)

顺便说一句,您的尝试done<$changed_files将假定它changed_files代表一个文件。

于 2014-09-24T17:42:59.963 回答
0

这里发生的是你的变量的值$changed_files被替换到你的命令中,你会得到类似的东西

while read each_file
do
        echo "Inside Loop -- $each_file"
done < archive/Crow.java 
archive/Kaka.java
mypmdhook.sh

然后外壳程序尝试打开文件以重定向输入并且显然失败了。

关键是重定向(例如<, >, >>)在大多数情况下都接受文件名,但您真正需要的是将变量的内容提供给标准输入。最明显的方法是

echo $changed_files | while read each_file; do echo "Inside Loop -- $each_file"; done

您也可以使用for循环代替while read

for each_file in $changed_files; do echo "inside Loop -- $each_file"; done

while read ...如果某些文件名可能包含空格,我更喜欢使用,但在大多数情况下for ... in对您有用。

于 2014-09-24T20:16:12.090 回答