删除 UID > 1000 的用户

删除 UID > 1000 的用户

如何编写一个 shell 脚本来删除 Linux 系统上所有 UID > 1000 的本地用户帐户?

这是我到目前为止所拥有的:

#!/bin/bash

for userid in `/etc/passwd`
do
if ((“userid” >= 1000)); then
userdel -r $user
done

如何设置删除所有 UID > 1000 的账户的条件?这是我没能找到的部分。我什至不确定到目前为止我所做的是否正确,但我在其他一些帖子上读到了它,该帖子有类似的问题,但略有不同。

答案1

以下awk命令将输出 UID 大于或等于 1000 的所有本地用户的用户名,并会跳过名称为 的任何用户nobody(这是您最有可能的用户)想要删除):

awk -F : '$3 >= 1000 && $1 != "nobody" { print $1 }' /etc/passwd

它将/etc/passwd文件解析为一组带有 -:分隔字段的基于行的记录。它测试第三个字段的值是否大于或等于 1000,确保第一个字段不是nobody,然后打印第一个字段。您可能希望将第二个测试更改为$1 != "nobody"避免$3 < 10000访问任何具有高 UID 的特殊帐户。

然后,您可以使用循环来读取名称并一次删除它们(请参阅史蒂芬的回答了解如何使用xargs来执行此操作):

awk -F : '$3 >= 1000 && $1 != "nobody" { print $1 }' /etc/passwd |
while IFS= read -r name; do
    userdel -r "$name"
done

答案2

应该是这样的:

getent passwd |
  awk -F: '$3 >= 1000 {print $1}' |
  xargs -n1 -rd '\n' echo userdel -r --

echo(如果看起来正确,则删除)。这假定了 的 GNU 实现xargs,但这通常用于非嵌入式 Linux 系统(您将在其上进行用户管理的系统)。

getent passwd转储 passwd 用户数据库,无论它是否存储在/etc/passwd、postgresql、sqlite3、LDAP...

在该数据库转储中,条目以冒号分隔,第一个字段是用户名,第三个字段是用户 ID。

awk是处理此类数据的明显选择。

我们使用-F:( 的缩写-v FS=:)调用它,将字段分隔符设置为:,并且对于每条记录,如果第三个字段是大于或等于 1000 的数字,我们将打印第一个字段。

xargs获取该输出(被视为newlined限制),并且对于每个1条目,使用echo、和该条目作为参数调用 、 userdel、 。-r--

如果您只想考虑 中的用户名,请替换getent passwd |为。</etc/passwd/etc/passwd

正如@Kusalananda 所说,可能有一些系统帐户,例如nobody您不想删除的帐户。

例如,在我的系统上,我发现:

libvirt-qemu:x:64055:108:Libvirt Qemu,,,:/var/lib/libvirt:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

因此,您可能想在您的选择中添加更多条件,例如$3 >= 1000 && $3 < 60000$3 >= 1000 && $6 ~ "^/home/"(下的主目录/home)或$7 !~ "nologin"(shell 不包含 nologin),或某个组的成员身份,或具有有效的密码...

请注意,userdel标准输入将是 /dev/null,因此它将无法提示您任何内容。为了避免这种情况,您可以将其改写为:

xargs -n1 -rd '\n' -a <(
    getent passwd |
      awk -F: '$3 >= 1000 {print $1}'
  ) echo userdel -r --

这次xargs从后面传递的文件-a而不是 stdin 中获取输入,并userdel单独保留 stdin 。

在这种情况下,文件名是 ksh 风格的进程替换(bash 也支持)的结果,其中<(...)扩展为管道的路径,末尾由getent | awk.

相关内容