找到匹配项后,使用 sed(或 awk)在 fstab 中添加条目
Use sed (or awk) to add entry in fstab when match found
我需要将 /etc/fstab 和 add/change fsoptions 中的行编辑为找到匹配卷的行。我曾尝试使用 sed 并将找到的块放入寄存器以将它们放回去,但我发现这是一个挑战。也许 sed 不是最好的工具——我尝试了 augeas,虽然它附加了它,但它没有替换,如果没有找到匹配的行但需要添加它也会失败(例如,只有使用 'mount' 命令才可见,例如/dev/shm).
例如,如果 /etc/fstab 有一行:
/dev/mapper/VolGroup1-tmp /tmp xfs dev,nosuid 0 0
我想去
/dev/mapper/VolGroup1-tmp /tmp xfs nodev,nosuid,noexec 0 0
- 请注意,第一个块中的卷组可以是任何名称
- 字符串中的 KEYWORD(在此示例中)为 /tmp(但注意不要匹配 /var/tmp,除非指定)
- 文件系统可以是任何东西(不一定是 xfs)
- 任何 'exec' 或 'suid' 存在(例如)如果存在则需要替换,即使不存在,也需要插入 'noexec' 或 'nosuid'。
- 需要保留尾随的“0 0”。
我确定我错过了一个简单的方法来做到这一点。使用 'mount -o remount,noexec /tmp' 不会写入 /etc/fstab 所以我想使更改持久化的唯一方法是直接编辑 /etc/fstab?
实际上我打算将解决方案包装在 Puppet 中。下面的 augeas 示例在两个方面失败了:
如果 /etc/fstab 中不存在某行(例如 /dev/shm),则失败
如果一行存在并且有 'exec' 它附加 'noexec' 但也留下 exec
augeas{ "/etc/fstab - ${opt} on ${mount}":
context => '/files/etc/fstab',
changes => [
"ins opt after /files/etc/fstab/*[file = '${mount}']/opt[last()]",
"set *[file = '${mount}']/opt[last()] ${opt}",
],
onlyif => "match *[file = '${mount}']/opt[. = '${opt}'] size == 0",
notify => Exec["remount_${mount}_${opt}"],
}
I'm sure I am missing an easy way to do this. Using 'mount -o
remount,noexec /tmp' doesn't write to /etc/fstab so I guess the only
way to make changes persistent is to edit /etc/fstab directly?
/etc/fstab 中没有用于修改挂载记录的专用 CLI,如果您是这个意思的话。使用文本编辑器手动编辑文件是老派的方式。
正如我在评论中提到的,使用装载记录的标准 Puppet 方法是通过 Mount
资源。只要我正在写一个答案,我就会重复使用这些是你应该做的工作的方式。
您在评论中反对
the issue is that the first string (fsname) could be anything, as could the fstype. I also want to preserve existing fsoptions that don't clash with new desired settings.
是问题所在,但不是我想的那样。您正处于一个紧要关头,因为您正试图在节点配置的这一方面容纳多个权限。最佳做法是将大量利益的责任完全交给 Puppet。它具有足够的灵活性,可以在不同的机器上提供不同的安装配置。
不过,如果你下定决心要这样使用Puppet,那也是可以的。但是,尽管这项任务描述起来相对容易,但细节使其相对复杂。基于 sed
的方法是可能的,但会相对冗长且极其神秘。一个更好的主要工作命令行工具是 awk
,特别是,这个 awk
脚本将完成您提出的案例的工作:
~ /^#.*/ || != "/tmp" {print; next}
~ /.*nosuid.*/ && ~ /.*noexec.*/ {print; next}
{
split(, opts, ",")
printf "%s %s %s ", , ,
for (i in opts) {
if (opts[i] !~ /(no)?(exec|suid)/) {
printf "%s,", opts[i]
}
}
printf "noexec,nosuid %s %s\n", ,
}
将其包装到 Exec
资源中并根据您的特定要求进行任何其他调整留作练习。
我需要将 /etc/fstab 和 add/change fsoptions 中的行编辑为找到匹配卷的行。我曾尝试使用 sed 并将找到的块放入寄存器以将它们放回去,但我发现这是一个挑战。也许 sed 不是最好的工具——我尝试了 augeas,虽然它附加了它,但它没有替换,如果没有找到匹配的行但需要添加它也会失败(例如,只有使用 'mount' 命令才可见,例如/dev/shm).
例如,如果 /etc/fstab 有一行:
/dev/mapper/VolGroup1-tmp /tmp xfs dev,nosuid 0 0
我想去
/dev/mapper/VolGroup1-tmp /tmp xfs nodev,nosuid,noexec 0 0
- 请注意,第一个块中的卷组可以是任何名称
- 字符串中的 KEYWORD(在此示例中)为 /tmp(但注意不要匹配 /var/tmp,除非指定)
- 文件系统可以是任何东西(不一定是 xfs)
- 任何 'exec' 或 'suid' 存在(例如)如果存在则需要替换,即使不存在,也需要插入 'noexec' 或 'nosuid'。
- 需要保留尾随的“0 0”。
我确定我错过了一个简单的方法来做到这一点。使用 'mount -o remount,noexec /tmp' 不会写入 /etc/fstab 所以我想使更改持久化的唯一方法是直接编辑 /etc/fstab?
实际上我打算将解决方案包装在 Puppet 中。下面的 augeas 示例在两个方面失败了:
如果 /etc/fstab 中不存在某行(例如 /dev/shm),则失败
如果一行存在并且有 'exec' 它附加 'noexec' 但也留下 exec
augeas{ "/etc/fstab - ${opt} on ${mount}": context => '/files/etc/fstab', changes => [ "ins opt after /files/etc/fstab/*[file = '${mount}']/opt[last()]", "set *[file = '${mount}']/opt[last()] ${opt}", ], onlyif => "match *[file = '${mount}']/opt[. = '${opt}'] size == 0", notify => Exec["remount_${mount}_${opt}"],
}
I'm sure I am missing an easy way to do this. Using 'mount -o remount,noexec /tmp' doesn't write to /etc/fstab so I guess the only way to make changes persistent is to edit /etc/fstab directly?
/etc/fstab 中没有用于修改挂载记录的专用 CLI,如果您是这个意思的话。使用文本编辑器手动编辑文件是老派的方式。
正如我在评论中提到的,使用装载记录的标准 Puppet 方法是通过 Mount
资源。只要我正在写一个答案,我就会重复使用这些是你应该做的工作的方式。
您在评论中反对
the issue is that the first string (fsname) could be anything, as could the fstype. I also want to preserve existing fsoptions that don't clash with new desired settings.
是问题所在,但不是我想的那样。您正处于一个紧要关头,因为您正试图在节点配置的这一方面容纳多个权限。最佳做法是将大量利益的责任完全交给 Puppet。它具有足够的灵活性,可以在不同的机器上提供不同的安装配置。
不过,如果你下定决心要这样使用Puppet,那也是可以的。但是,尽管这项任务描述起来相对容易,但细节使其相对复杂。基于 sed
的方法是可能的,但会相对冗长且极其神秘。一个更好的主要工作命令行工具是 awk
,特别是,这个 awk
脚本将完成您提出的案例的工作:
~ /^#.*/ || != "/tmp" {print; next}
~ /.*nosuid.*/ && ~ /.*noexec.*/ {print; next}
{
split(, opts, ",")
printf "%s %s %s ", , ,
for (i in opts) {
if (opts[i] !~ /(no)?(exec|suid)/) {
printf "%s,", opts[i]
}
}
printf "noexec,nosuid %s %s\n", ,
}
将其包装到 Exec
资源中并根据您的特定要求进行任何其他调整留作练习。