尝试使用“useradd”编写脚本,无法理解示例

尝试使用“useradd”编写脚本,无法理解示例

我正在尝试使用useradd.我找到了一个我想尝试并合并的示例,尽管我无法理解具体部分。

这是完整的示例:

if [ $(id -u) -eq 0 ]; then
read -p "Enter username : " username
read -s -p "Enter password : " password
egrep "^$username" /etc/passwd >/dev/null
if [ $? -eq 0 ]; then
    echo "$username exists!"
    exit 1    

我了解正在发生的基本情况,但具体来说:

[ $(id -u) -eq 0 ];

[ $? -eq 0 ];

我猜括号内正在创建一个变量。但我一直难以理解它们的目的或意义。

答案1

来自男人:

-u,--用户

        print only the effective user ID

id -u将打印用户的 ID。该脚本仅限于 UID 为 0 的 root 用户。

$?先前执行的命令的退出状态。

答案2

id实用程序在与其-u选项一起使用时,将输出当前用户的 UID。如果该 UID 为零,则该用户是 root 用户。只有 root 用户才可以添加新用户。

因此,该脚本会再次测试运行该脚本的用户的 UID 为零,并且仅在用户是 root 的情况下才执行特权操作(问题中的脚本中未显示)。

如果整个脚本需要 root,在脚本中处理此问题的一个可以说更好的方法是在开始时检查 UID 是否非零,如果是,则退出并显示错误:

if [ "$(id -u)" -ne 0 ]; then
    echo 'You are not root.  Try again with sudo.' >&2
    exit 1
fi

至于$?,它是一个特殊的 shell 变量,始终包含最近执行的命令的退出状态。这是很稀少需要直接使用它,因为if它不仅能够直接使用grep

if grep -q "^$username" /etc/passwd; then
    printf 'User "%s" already exists\n' "$username" >&2
    exit 1
fi

这里,if将使用 的退出状态grep。我们使用grepwith-q来阻止它产生任何输出并解析所有的文件超过任何第一个匹配项。它只是返回一个将使用的退出状态if。我们也不需要,egrep因为正则表达式不是扩展正则表达式(egrep与 相同grep -E)。

另请注意,诊断消息应写入标准错误流。您可以通过使用 重定向您的消息来做到这一点>&2。还,printf优于echo输出可变数据时

如果您所在的系统使用 NIS 或 LDAP 等目录服务,则 grep 查找现有用户/etc/passwd可能没有用,因为实际用户可能存储在单独的数据库中。

在此类系统上,使用它可能会更好getent passwd "$username"(这也适用于非 NIS/LDAP 系统)。这将返回特定用户的密码数据库条目,或者以非零退出状态退出,这意味着我们可以使用在我们的测试中:

if getent passwd "$username" >/dev/null; then
    printf 'User "%s" already exists\n' "$username" >&2
    exit 1
fi

请注意,useradd无法将用户添加到 NIS 或 LDAP 数据库...

不过,严格来说,上面的内容实际上都不需要,因为useradd如果当前用户不是 root 或者如果添加的用户已经存在,则不会做任何有用的事情。

相关内容