为了编写自动安装和配置Fail2Ban的脚本,我需要一种方法来修改/etc/fail2ban/jail.local。我的问题是,我需要在文件的特定部分添加一行,但前提是该区域中不存在模式enabled = true
。还有其他领域不应该写enable = true
。
以下seds工作正常,但不检查是否已有enabled = true
:
sed '/\[apache-auth\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local
sed '/\[apache-badbots\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local
sed '/\[apache-noscript\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local
sed '/^\[sshd\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local
更新添加所需信息
原始文件
[sshd]
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
[apache-auth]
port = http,https
logpath = %(apache_error_log)s
[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
port = http,https
logpath = %(apache_access_log)s
bantime = 172800
maxretry = 1
[apache-noscript]
port = http,https
logpath = %(apache_error_log)s
预期输出
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
#
# HTTP servers
#
[apache-auth]
enabled = true
port = http,https
logpath = %(apache_error_log)s
[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
enabled = true
port = http,https
logpath = %(apache_access_log)s
bantime = 172800
maxretry = 1
[apache-noscript]
enabled = true
port = http,https
logpath = %(apache_error_log)s
英语不是我的母语,所以请不要判断我的拼写错误。我也不确定,如果这是本课题的正确网站。
答案 0 :(得分:2)
这可能适合你(GNU sed):
sed -nr '/^\[(apache-(auth|loadbots|noscript)|sshd)\]/{:a;x;/./!bb;/enabled = true/!s/^\w/enabled = true\n&/M;p;:b;x;h;d};H;$ba;d' file
这将该部分存储在保留空间中,如果它尚不存在则插入enabled = true
并打印出该部分。
详细说明:
command line switches -r
和-n
已激活,这样可以更容易地为前一个和可选的打印表达正则表达式(grep-like,即命令p
或对于后者,P
必须存在。
该命令由if-then-else。
组成如果当前行以[
开头并且包含四个单词之一,然后是]
,则{
和}
之间的命令将被执行。
打开{
后的第一个命令是占位符,在满足文件结束条件时使用。
x
表示使用保留空间(HS)切换模式空间(PS)。 Sed有two registers,PS是当前行(减去换行符)读入的地方。 HS是一个备用寄存器,由程序员自行决定使用。
下一个命令/./!bb
检查HS是否为空(如果这是第一次执行此代码,那将是这样),如果是,则跳转到:b
名称空间,输出以下代码。
现在已知HS包含一行或多行,检查这些行是否包含字符串enabled = true
,如果不包含,则在第一行的前面插入字符串enabled = true
以单词字符开头。
无论匹配或不匹配,HS都会使用p
命令打印。
分支名称空间现在被加载:b
并且HS和PS被交换,当前行替换HS h
中的任何内容然后删除d
,这结束了处理那条线。
如果第一个正则表达式失败:当前行被附加到HS H
并被删除d
,除非它是最后一行,在这种情况下处理被定向到名称空间{{1}通过命令:a
。这涵盖了文件结束条件,其中HS中的行将需要如上所述进行处理。
答案 1 :(得分:0)
awk
救援!
awk -v sections='sshd apache-auth apache-badbots apache-noscript' -v RS= -v ORS="\n\n" '
BEGIN {n=split(sections,a);
for(i=1; i<=n; i++) sec["["a[i]"]"]}
$1 in sec {$2 = "\nenabled = true\n"}1' file
维护sections变量中的标记,并为相应的部分插入所需的行。期望节标题是该行的唯一条目。