首页 > 解决方案 > 找到匹配项时使用 sed(或 awk)在 fstab 中添加条目

问题描述

我需要编辑 /etc/fstab 中的行并将 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
  1. 请注意,第一个块中的卷组可以是任何名称
  2. 字符串中的 KEYWORD 将(在此示例中)为 /tmp(但注意不要匹配 /var/tmp,除非指定)
  3. 文件系统可以是任何东西(不一定是 xfs)
  4. 任何存在的 'exec' 或 'suid' (例如)都需要被替换(如果存在),即使不存在,也需要插入 'noexec' 或 'nosuid'。
  5. 需要保留尾随的“0 0”。

我确定我错过了一种简单的方法来做到这一点。使用 'mount -o remount,noexec /tmp' 不会写入 /etc/fstab 所以我想使更改持久化的唯一方法是直接编辑 /etc/fstab?

我实际上打算将解决方案包装在 Puppet 中。下面的 augeas 示例在 2 个方面失败:

标签: bashsedpuppetaugeasfstab

解决方案


我确定我错过了一种简单的方法来做到这一点。使用 'mount -o remount,noexec /tmp' 不会写入 /etc/fstab 所以我想使更改持久化的唯一方法是直接编辑 /etc/fstab?

没有用于修改 /etc/fstab 中的挂载记录的专用 CLI,如果这就是您的意思。使用文本编辑器手动编辑文件是老式的方法。

正如我在评论中提到的,使用装载记录的标准 Puppet 方法是通过Mount资源。只要我在写答案,我就重复一遍,使用这些是你应该做的工作方式。

你在评论中反对

问题是第一个字符串(fsname)可以是任何东西,fstype 也可以。我还想保留与新的所需设置不冲突的现有 fsoptions。

就是问题所在,但不是我认为你的意思。您正处于困境,因为您正试图在节点配置的这方面适应多个权限。最好的做法是把利益的责任完全交给 Puppet。它具有足够的灵活性,可以在不同的机器上提供不同的安装配置。

不过,如果你下定决心要这样使用Puppet,那也是可以的。但是,尽管任务相对容易描述,但细节使其相对复杂。基于-sed的方法是可能的,但会相对冗长且极其神秘。用于主要工作的更好的命令行工具是awk,特别是,此awk脚本将为您提供的案例完成工作:

$1 ~ /^#.*/ || $2 != "/tmp" {print; next}
$4 ~ /.*nosuid.*/ && $4 ~ /.*noexec.*/ {print; next}
{
  split($4, opts, ",")
  printf "%s    %s  %s  ", $1, $2, $3
  for (i in opts) {
    if (opts[i] !~ /(no)?(exec|suid)/) {
      printf "%s,", opts[i]
    }
  }
  printf "noexec,nosuid %s %s\n", $5, $6
}

将其包装到Exec资源中并对您的特定要求进行任何其他调整都留作练习。


推荐阅读