使用Shell中的密码自动创建用户帐户
1. 概述
有时,我们可能希望自动化用户创建过程,而无需与命令行交互。
在本教程中,我们将编写一个强大的 shell 脚本来自动化用户创建过程。我们将使用大多数 Linux 发行版附带的内置工具,在学习本教程的各个部分时构建我们的脚本。最后,我们将拥有一个健壮的 shell 脚本,我们可以手动或从另一个程序执行它。
2. 设置自动化脚本
我们将首先执行验证检查,例如检查用户是否已经存在,如果没有提供则分配默认密码。之后,我们将介绍实际用户创建和密码分配的一些变化。
2.1. 基本用法
我们将从命令行执行脚本并为其提供*-username和-password*参数。如果出现验证错误,我们将看到包含说明的脚本使用消息。一旦脚本成功执行,我们将打印出用户名和密码。
让我们从创建脚本文件和编写usage函数开始:
#!/bin/sh
usage() {
printf "create-user [-u|--username] <username>\n"
printf " OPTIONS\n"
printf " -u --username\tusername of the new account (required)\n"
printf " -p --password\tpassword for the new account (optional)\n"
printf " -h --help\tprint this help\n"
exit 1
}
**如果出现错误,我们将调用usage函数。**在我们的脚本中包含usage函数是 UNIX 和 Linux 的约定。
2.2. 进程命令选项
现在,我们需要处理命令选项。**我们将简单地使用while循环遍历参数并将值分配给变量。**之后,我们将进行一些完整性检查,如果没有提供密码作为参数,我们将分配一个默认密码。
让我们处理usage函数之后的参数:
while [ "$#" -gt 0 ]; do
case "$1" in
-u|--username) username="$2" shift ;;
-p|--password) password="$2" shift ;;
-h|--help) usage ;;
*) usage ;;
esac
shift
done
[ -z "$username" ] && usage
[ -z "$password" ] && password=$(uuidgen | cut -d'-' -f1)
如果没有提供用户名,我们会打印出脚本的用法并使用退出代码 1 退出程序。在缺少密码的情况下,我们使用了uuidgen 命令来生成 UUID。在我们的例子中,我们只需要生成的 UUID 的前八个字符作为默认密码。
2.3. 检查用户是否存在
有时,我们可能有一个现有用户,其用户名与username参数相同。因此,我们需要事先检查用户数据库中的现有用户。我们可以使用userdbctl 命令。我们使用 userdbctl命令来查询 Linux 机器上的用户数据库。
userdbctl命令为用户数据库中不存在的用户返回退出代码1。否则,它将返回 0:
userdbctl user "$username" > /dev/null 2>&1
[ "$?" -eq 0 ] && echo "$username already exists" && exit 2
在上面的代码片段中,我们运行userdbctl命令并检查它返回的退出代码。** $?运算符包含我们在脚本中执行的最新命令的退出代码。在这种情况下,它将包含 0 或 1。
当然,我们可以离开这个安全检查,因为如果用户已经存在,useradd 命令将失败。但是,我们需要某种与我们的脚本配合得很好的简单反馈,因为useradd将为已经存在的用户名返回退出代码 9。
3. 创建用户并分配密码
现在预检查已完成,我们将继续创建实际用户。我们将使用useradd命令来创建用户。为了分配密码,我们将展示一些变体。
3.1. 带有*-p*选项的用户添加
useradd 命令使用 提供的用户名创建用户。我们还可以通过向useradd命令提供-p或–password*选项来创建带有密码的用户*:
$ useradd -m newuser -p strongpassword
$ userdbctl user newuser
User name: newuser
Disposition: regular
Login OK: yes
Password OK: yes
UID: 1004
GID: 1004 (newuser)
Directory: /home/newuser
Storage: classic
Shell: /bin/bash
Passwords: none
-m标志为用户创建一个主目录。让我们在脚本中使用上述命令,并为其提供username和password变量:
useradd -m "$username" -p "$password" > /dev/null 2>&1
3.2. useradd、echo和passwd命令
passwd 命令创建或更改现有用户帐户的密码。它将用户名作为参数,并提供密码修改的交互式提示。
让我们更改刚刚创建的新用户的密码:
$ passwd newuser
Changing password for newuser.
Current password:
New password:
Retype new password:
passwd: password updated successfully
正如我们所见,passwd命令向我们展示了一个交互式提示。出于这个原因,我们将在passwd旁边使用echo命令来跳过交互式提示。
echo 命令是一个实用程序,它从标准输入中获取输入并将其打印到标准输出。我们还可以通过管道 echo与其他命令一起绕过提示和确认消息。因此,我们可以轻松地自动化涉及 shell 脚本或 Linux 终端中的提示的任务。
让我们看看它的实际效果:
$ echo -en "strongpassword\nnewpass\nnewpass\n" | passwd newuser
Changing password for newuser.
Current password:
New password:
Retype new password:
passwd: password updated successfully
这是发生的事情:
- 我们通过*-e标志为echo命令启用了转义序列字符*支持
- -n标志禁用打印尾随换行符
- 我们回显当前密码,然后是新的和确认的密码
- 每个密码都由“\n”字符分隔,因此它们被视为三个独立的标准输入
- echo命令的输出通过 管道传送到passwd命令,我们用它来更改newuser的密码
现在我们对如何使用echo绕过提示有了一些了解,我们可以在脚本中实现这一点,而不是向useradd命令提供密码:
useradd -m "$username" > /dev/null 2>&1
echo -n "$password\n$password\n" | passwd "$username" /dev/null 2>&1
3.3. useradd、echo和chpasswd命令
或者,我们可以使用chpasswd 命令更改新用户的密码。它执行与passwd相同的功能。
让我们看看它的实际效果:
$ chpasswd
newuser:secretpasscode
与 passwd一样,chpasswd将向我们展示一个交互式多行提示。我们写下用户名,后跟冒号*(:)和新密码。之后,我们可以按 CTRL+D 来应用更改。像passwd一样,我们也可以使用echo*命令来自动化这个过程:
$ echo "newuser:code7654" | chpasswd
现在我们已经熟悉了chpasswd ,我们可以在脚本中使用它来代替passwd:
useradd -m "$username"
echo "${username}:${password}" | chpasswd
4.收尾工作
我们的脚本几乎完成了。现在,我们需要编写反馈代码,让用户知道用户创建成功。
我们将检查脚本中执行的最新命令的退出代码,可能是useradd、passwd或chpasswd,具体取决于使用的变体:
if [ "$?" -eq 0 ]; then
echo "Username: $username"
echo "Password: $password"
else
echo "Failed to set up user account"
userdel -f "$username"
fi
让我们分解一下:
- 我们检查先前执行的命令的退出代码,并期望它等于 0
- 如果是0,通常表示成功,我们打印出用户名和密码
- 在失败的情况下,我们打印出失败消息并使用userdel 命令从用户数据库中删除用户(如果它已创建)
- -f标志强制 userdel删除用户——即使用户仍然登录——连同他们的主目录和邮件假脱机
我们现在准备测试脚本:
$ ./create-user -u "johndoe" -p "ys2b7444"
Username: johndoe
Password: ys2b7444
$ ./create-user -u "doejohn"
Username: doejohn
Password: 89c871de
$ ./create-user -u johndoe
johndoe already exists
$ ./create-user
create-user [-u|--username] <username>
OPTIONS
-u --username username of the new account (required)
-p --password password for the new account (optional)
-h --help print this help
我们的create-user脚本现已完成:
#!/bin/sh
usage() {
printf "create-user [-u|--username] <username>\n"
printf " OPTIONS\n"
printf " -u --username\tusername of the new account (required)\n"
printf " -p --password\tpassword for the new account (optional)\n"
printf " -h --help\tprint this help\n"
exit 1
}
while [ "$#" -gt 0 ]; do
case "$1" in
-u|--username) username="$2" shift ;;
-p|--password) password="$2" shift ;;
-h|--help) usage ;;
*) usage ;;
esac
shift
done
[ -z "$username" ] && usage
[ -z "$password" ] && password=$(uuidgen | cut -d'-' -f1)
useradd -m "$username" -p "$password" > /dev/null 2>&1
#------------#
# VARIATIONS #
#------------#
# useradd -m "$username"
# echo -n "$password\n$password\n" | passwd $username"
# echo "${username}:${password}" | chpasswd
if [ "$?" -eq 0 ]; then
echo "Username: $username"
echo "Password: $password"
else
echo "Failed to set up user account"
userdel -f "$username"
fi