我有一个简单的 bash 脚本,它从文本文件中读取行,如下所示:
#!/bin/bash
FILE=$1
while read line; do
...
done < $FILE
效果很好,但现在我想首先使用 grep 解析文件,如下所示:
INPUT_file=$(grep -E 'INPUT.*ACCEPT' $FILE)
然后将该结果分配给变量 INPUT_file
我现在想从变量“INPUT_file”读取行,但是当我尝试包含在 while 循环中时:
while read line; do
....
done < $INPUT_file
我收到以下错误:
$INPUT_file: ambiguous redirect
答案1
你最好使用流程替代而不是变量:
while read line; do
....
done < <(grep -E 'INPUT.*ACCEPT' $FILE)
(注意两个<
字符)。这避免了一次将整个grep
输出加载到内存中以存储在变量中。该grep
过程将与循环并行运行,并且循环将在每行打印出来时grep
将 的输出视为 的read
输入(直到缓冲)。
$(...)
与使用命令替换并保留整个输出相比,这往往会更快并且使用更少的内存。如果您正在编写特定于 Bash 的脚本,那么它通常也是更好的风格,因为它明确说明了您使用该命令的用途。
可以说,这有点像反模式——您可能最好仍然使用普通管道来进行所需的任何处理,而不是while read ...
在 Bash 中处理它,但是使用这两种方法都有有效的情况。
答案2
那就是当这里的字符串发挥作用:
while read line; do
...
done<<<$INPUT_file
答案3
grep
在这种情况下您不应该调用。所有这些都可以仅使用您的 shell 来完成。例如
while read -r line; do [[ $line =~ INPUT.*ACCEPT ]] && printf '%s\n' "$line"; done < your_iptables_file