我希望创建一个可执行的 bash 脚本,它将以 root 身份运行以下命令,即使用 sudo su
iptables-save | awk '/^[*]/ { print $1 }
/^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
/COMMIT/ { print $0; }' | iptables-restore
我对 bash 脚本的第一次尝试如下:
#!/bin/bash
sudo su
iptables-save | awk '/^[*]/ { print $1 }
/^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
/COMMIT/ { print $0; }' | iptables-restore
sleep 3;
exit 0
有人可以纠正上述内容并使其可行吗?
答案1
Shell 脚本与在终端上键入不太一样。
这里将要iptables-save
等待sudo su
完成,然后运行。你想要的是iptables-save
在sudo
.
其次,sudo su
属于“无用之用”的例子。正确的等价物是
sudo -i
.
您可以采取两种方法来解决此问题。
方法一
sudo -i <<'EOF'
iptables-save | awk '/^[*]/ { print $1 }
/^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
/COMMIT/ { print $0; }' | iptables-restore
EOF
这基本上会启动一个 root shell 并通过该 shell 发送该命令。
我们不只是在和命令sudo
前面添加 a 的原因是它会同时启动 2 s。如果他们最终都尝试提示输入密码,则这种方法效果不佳。 因此,该解决方案通过仅启动一个.iptables-save
iptables-restore
sudo
sudo
一条线
根据您的评论中的要求,您可以在一行中完成此操作,但它变得更难以阅读。
sudo -i sh -c 'iptables-save | awk '\''/^[*]/ { print $1 }; /^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }; /COMMIT/ { print $0; }'\'' | iptables-restore'
方法2
sudo -v
sudo -n iptables-save | awk '/^[*]/ { print $1 }
/^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
/COMMIT/ { print $0; }' | sudo -n iptables-restore
该解决方案sudo
首次运行,无需任何命令,只需一个-v
.sudo
如果您的会话已过期,这会提示您输入密码。然后,在该会话过期窗口内运行的任何命令都不需要密码。因此,sudo
同时启动 2 个不再是问题,因为它们都不会提示(我们添加-n
以确保这一点。如果尝试,它会抛出错误)。