将输入文件中的多个参数多次传递给命令 (Bash)
Passing multiple arguments from input file, to a command multiple times (Bash)
我发现自己遇到过几种情况,在这些情况下,能够按行从输入文件中输入命令参数会很方便。在少数几次我希望能够做到这一点的时候,我最终找到了解决方法或 运行手动多次执行该命令。
我有一个包含多行的文件input.txt
,每行有任意个参数。我将以我最近对此功能的需求为例。我试图简单地将我的 iptables
规则复制到 ip6tables
。我有 运行 命令 iptables -S > input.txt
生成以下文件:
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT
对于每一行,我想 运行 类似 sudo ip6tables $line
的东西,以便 ip6tables
运行 包含给定行的所有参数,以及 N命令是 运行,其中 N 是 input.txt
.
中的行数
这个问题的答案应该适用于这种情况一般。我不是在寻找 仅 用于将 iptables
规则复制到 IPv6 副本的解决方案(例如,通过 iptables
中的某些功能)。如果可能的话,我也更喜欢可以在终端中执行的单行代码,而不是编写 bash 脚本。不过,如果 bash 脚本比单行脚本要简单得多,那么我也会接受它作为答案。
如果它仅用于 iptables
,您的系统可能已经有合适的 iptables-restore
命令,您只需调用:
sudo iptables-restore input.txt
现在如果要使用 input.txt
将参数传递给其他命令,有一个简单的解决方案 Bash:
arguments
是从input.txt
的每一行读取(填充)的数组
遍历 input.txt
文件的每一行。
像这样将 arguments
数组传递给您的命令:
#!/usr/bin/env bash
arguments=()
while read -r -a arguments; do
your_command "${arguments[@]}"
done <input.txt
对于上面的一行:
while read -ra a;do your_command "${a[@]}";done<input.txt
或者 POSIX 兼容版本(无数组):
while read -r a;do set -- $a; your_command "$@";done <input.txt
这听起来像是 xargs
的完美工作。对于您的 iptables
示例,它是这样工作的:
xargs -L 1 sudo ip6tables < input.txt
xargs
从 stdin 读取命令参数,并使用添加到命令行的参数执行提供的命令。这里的参数从 input.txt
文件通过管道传输到标准输入。 -L 1
每次执行将参数限制为一行,即在命令行中添加一行,执行生成的命令,继续下一行等。
我发现自己遇到过几种情况,在这些情况下,能够按行从输入文件中输入命令参数会很方便。在少数几次我希望能够做到这一点的时候,我最终找到了解决方法或 运行手动多次执行该命令。
我有一个包含多行的文件input.txt
,每行有任意个参数。我将以我最近对此功能的需求为例。我试图简单地将我的 iptables
规则复制到 ip6tables
。我有 运行 命令 iptables -S > input.txt
生成以下文件:
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT
对于每一行,我想 运行 类似 sudo ip6tables $line
的东西,以便 ip6tables
运行 包含给定行的所有参数,以及 N命令是 运行,其中 N 是 input.txt
.
这个问题的答案应该适用于这种情况一般。我不是在寻找 仅 用于将 iptables
规则复制到 IPv6 副本的解决方案(例如,通过 iptables
中的某些功能)。如果可能的话,我也更喜欢可以在终端中执行的单行代码,而不是编写 bash 脚本。不过,如果 bash 脚本比单行脚本要简单得多,那么我也会接受它作为答案。
如果它仅用于 iptables
,您的系统可能已经有合适的 iptables-restore
命令,您只需调用:
sudo iptables-restore input.txt
现在如果要使用 input.txt
将参数传递给其他命令,有一个简单的解决方案 Bash:
arguments
是从input.txt
遍历 input.txt
文件的每一行。
像这样将 arguments
数组传递给您的命令:
#!/usr/bin/env bash
arguments=()
while read -r -a arguments; do
your_command "${arguments[@]}"
done <input.txt
对于上面的一行:
while read -ra a;do your_command "${a[@]}";done<input.txt
或者 POSIX 兼容版本(无数组):
while read -r a;do set -- $a; your_command "$@";done <input.txt
这听起来像是 xargs
的完美工作。对于您的 iptables
示例,它是这样工作的:
xargs -L 1 sudo ip6tables < input.txt
xargs
从 stdin 读取命令参数,并使用添加到命令行的参数执行提供的命令。这里的参数从 input.txt
文件通过管道传输到标准输入。 -L 1
每次执行将参数限制为一行,即在命令行中添加一行,执行生成的命令,继续下一行等。