我想写一个bash脚本,它可以更新/etc/security/limits.conf
文件。
该文件可能包含以下内容:
* soft core 0
* hard rss 10000
@student hard nproc 20
@faculty soft nproc 20
@faculty hard nproc 50
ftp hard nproc 0
@student - maxlogins 4
假设我想这样运行脚本:
Usage:
update-ulimits <domain> <type> <item> <value>
Examples:
./update-ulimits '*' hard rss 20000
./update-ulimits bob hard nofile 1024
这将更改文件以包含:
* soft core 0
* hard rss 20000
@student hard nproc 20
@faculty soft nproc 20
@faculty hard nproc 50
ftp hard nproc 0
@student - maxlogins 4
bob hard nofile 1024
因此,如果文件已经包含一行具有domain
、type
和item
,它将替换value
,否则它将附加一行包含所有4个参数的新行。列不需要对齐。
这是一个特定的例子,其中只有几个元字符需要担心,但我很好奇是否有一个好的解决方案可以处理所有任意的元字符。我猜perl和awk应该能够做到这一点,但我对它们都不太熟悉。
一个awk
解决方案:
$ cat update-ulimits
#!/usr/bin/bash
domain="${1}" # OP can add code to verify inputs as needed
ltype="${2}"
item="${3}"
value="${4}"
awk -v dom="${domain}" -v type="${ltype}" -v item="${item}" -v val="${value}" '
($1 == dom) &&
($2 == type) &&
($3 == item) { $4 = val ; foundit=1 } # overwrite field 4
{ print } # print current line
END { if (! foundit) { print dom, type, item, val } } # if not found, print all inputs as a new line
' limits.conf
几个样本运行:
$ update-ulimits '*' hard rss 20000
* soft core 0
* hard rss 20000
@student hard nproc 20
@faculty soft nproc 20
@faculty hard nproc 50
ftp hard nproc 0
@student - maxlogins 4
$ update-ulimits bob hard nofile 1024
* soft core 0
* hard rss 10000
@student hard nproc 20
@faculty soft nproc 20
@faculty hard nproc 50
ftp hard nproc 0
@student - maxlogins 4
bob hard nofile 1024
注意:
- OP可以决定
awk
是否应该自动覆盖源文件(请参阅-i
标志,例如:使用awk将修改保存到位(,或者可能添加额外的代码,在覆盖原始文件之前先保存原始文件 - 由于向
limits.conf
添加新行时列对齐不是问题,所以我采取了简单的方法,不必为修改后的行维护空白;如果需要保留原始空白,请查看"如何在awk中保留字段之间的原始空白?"的答案
这不是一个好主意。如何选择要编辑的行?唯一真正的方法是指定一个匹配表达式,然后指定一个替换行/字段。即便如此,您也可能有多个匹配项。
一种更快的方法是只打印每行带数字的行,并让用户选择一行进行编辑。此时,您还可以在文本编辑器中打开它。
我的建议是学习sed
和awk
。然后,无论何时需要对文件执行特定的编辑工作,都可以。
编辑-如果你只想替换一个值:
sed -E s'/(^<match-fields>s+)([0-9]+s*$)/1<new-number>/'