我正在尝试使用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
。我们使用grep
with-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 或者如果添加的用户已经存在,则不会做任何有用的事情。