newusers 是 Linux 中一个批量创建或更新用户账户的命令。它通过读取包含用户信息的文本文件,一次性创建或修改多个系统用户,非常适合批量用户管理场景。
📖 基本语法
bash
newusers [选项] [用户文件]
重要特性:
- 批量创建用户账户
- 批量更新现有用户信息
- 从文件读取用户信息
- 支持加密密码
- 自动创建家目录
🎯 命令选项
| 选项 | 说明 |
|---|---|
-c |
使用 crypt() 方法加密密码(默认)。 |
-m |
为用户创建家目录(如果不存在)。 |
-r |
创建系统用户(UID < 1000)。 |
-s |
使用 SHA-512 加密密码。 |
-h |
显示帮助信息。 |
--badname |
允许不符合常规规则的用户名。 |
📝 用户文件格式
用户文件每行对应一个用户,包含8个字段,用冒号分隔:
用户名:密码:UID:GID:描述:家目录:shell
字段说明:
- 用户名:登录用户名(必须唯一)
- 密码 :加密后的密码(使用
openssl passwd或mkpasswd生成) - UID:用户ID(如果为0,系统自动分配)
- GID:主组ID(如果为0,系统自动分配)
- 描述:用户全名或描述信息(GECOS字段)
- 家目录:用户家目录路径
- shell:登录shell路径
💡 核心用法示例
1. 准备用户数据文件
bash
# 创建用户数据文件
cat > users.txt << 'EOF'
alice:$6$salt$encrypted:1001:1001:Alice Smith:/home/alice:/bin/bash
bob:$6$salt$encrypted:1002:1002:Bob Johnson:/home/bob:/bin/bash
charlie:$6$salt$encrypted:1003:1003:Charlie Brown:/home/charlie:/bin/bash
david:$6$salt$encrypted:1004:1004:David Wilson:/home/david:/bin/bash
eve:$6$salt$encrypted:1005:1005:Eve Davis:/home/eve:/bin/bash
EOF
# 生成加密密码的方法
# 方法1:使用 openssl(推荐)
openssl passwd -6 -salt $(openssl rand -base64 6) "用户密码"
# 方法2:使用 mkpasswd(需要安装 whois 包)
mkpasswd -m sha-512 "用户密码"
# 方法3:使用 Python
python3 -c "import crypt; print(crypt.crypt('用户密码', crypt.mksalt(crypt.METHOD_SHA512)))"
# 方法4:使用 Perl
perl -e 'print crypt("用户密码", "\$6\$" . rand_string(8) . "\$") . "\n"'
2. 批量创建用户
bash
# 基本用法:批量创建用户
sudo newusers users.txt
# 创建用户并自动创建家目录
sudo newusers -m users.txt
# 创建系统用户(UID < 1000)
sudo newusers -r users.txt
# 使用 SHA-512 加密密码
sudo newusers -s users.txt
# 创建用户并允许非常规用户名
sudo newusers --badname users.txt
# 组合选项:创建家目录并使用 SHA-512 加密
sudo newusers -m -s users.txt
3. 批量更新用户
bash
# 更新现有用户信息
# 注意:用户名必须已存在,其他字段会被更新
cat > update_users.txt << 'EOF'
alice:$6$newsalt$newencrypted:1001:1001:Alice Smith Updated:/home/alice:/bin/zsh
bob:$6$newsalt$newencrypted:1002:1002:Bob Johnson Updated:/home/bob:/bin/bash
EOF
sudo newusers update_users.txt
4. 从 CSV 文件转换
bash
# 假设有 CSV 文件 users.csv,格式为:
# username,fullname,password,uid,gid,homedir,shell
# alice,Alice Smith,password123,1001,1001,/home/alice,/bin/bash
# 转换 CSV 到 newusers 格式
cat users.csv | while IFS=',' read -r username fullname password uid gid homedir shell; do
# 生成加密密码
encrypted_pass=$(openssl passwd -6 -salt $(openssl rand -base64 6) "$password")
echo "$username:$encrypted_pass:$uid:$gid:$fullname:$homedir:$shell"
done > users_newusers.txt
# 创建用户
sudo newusers -m users_newusers.txt
🔧 完整操作示例
示例1:批量创建公司员工账户
bash
#!/bin/bash
# 批量创建员工账户脚本
# 定义用户数据文件
USER_FILE="/tmp/employees.txt"
PASSWORD="Chang3Me!2024" # 初始密码,首次登录后需修改
BASE_UID=2000
BASE_GID=2000
# 员工信息数组
declare -A employees=(
["zhangsan"]="张三"
["lisi"]="李四"
["wangwu"]="王五"
["zhaoliu"]="赵六"
["qianqi"]="钱七"
)
# 生成加密密码
encrypted_pass=$(openssl passwd -6 -salt $(openssl rand -base64 6) "$PASSWORD")
# 创建用户数据文件
echo "# 员工账户信息" > "$USER_FILE"
echo "# 生成时间: $(date)" >> "$USER_FILE"
echo "# 初始密码: $PASSWORD" >> "$USER_FILE"
echo "======================================" >> "$USER_FILE"
counter=0
for username in "${!employees[@]}"; do
fullname="${employees[$username]}"
uid=$((BASE_UID + counter))
gid=$((BASE_GID + counter))
homedir="/home/$username"
echo "$username:$encrypted_pass:$uid:$gid:$fullname:$homedir:/bin/bash" >> "$USER_FILE"
((counter++))
done
# 显示生成的文件
echo "生成的用户文件内容:"
cat "$USER_FILE"
echo ""
echo "======================================"
# 确认是否创建
read -p "是否创建以上用户?(y/n): " confirm
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
echo "开始创建用户..."
sudo newusers -m "$USER_FILE"
# 设置密码过期,强制首次登录修改
for username in "${!employees[@]}"; do
sudo chage -d 0 "$username"
echo "已设置用户 $username 首次登录必须修改密码"
done
echo "用户创建完成!"
echo "请通知员工使用初始密码登录并立即修改密码"
else
echo "已取消操作"
fi
# 清理临时文件
rm -f "$USER_FILE"
示例2:从 LDAP/AD 导出并创建用户
bash
#!/bin/bash
# 从 LDAP 导出用户并创建本地账户
# LDAP 搜索命令(示例)
# ldapsearch -x -H ldap://ldap.example.com -b "ou=users,dc=example,dc=com" "(objectClass=posixAccount)"
# 模拟 LDAP 导出数据
cat > ldap_export.csv << 'EOF'
username,uid,gid,gecos,homedir,shell
jsmith,1001,1001,John Smith,/home/jsmith,/bin/bash
bjones,1002,1002,Bob Jones,/home/bjones,/bin/bash
kmiller,1003,1003,Karen Miller,/home/kmiller,/bin/bash
dwilson,1004,1004,David Wilson,/home/dwilson,/bin/bash
slee,1005,1005,Sarah Lee,/home/slee,/bin/bash
EOF
# 转换函数
convert_ldap_to_newusers() {
local input_file="$1"
local output_file="$2"
local default_password="Welcome123"
echo "# 从 LDAP 导入的用户" > "$output_file"
echo "# 生成时间: $(date)" >> "$output_file"
# 跳过标题行
tail -n +2 "$input_file" | while IFS=',' read -r username uid gid gecos homedir shell; do
# 清理可能的空格
username=$(echo "$username" | tr -d '[:space:]')
uid=$(echo "$uid" | tr -d '[:space:]')
gid=$(echo "$gid" | tr -d '[:space:]')
gecos=$(echo "$gecos" | tr -d '[:space:]')
homedir=$(echo "$homedir" | tr -d '[:space:]')
shell=$(echo "$shell" | tr -d '[:space:]')
# 生成加密密码
encrypted_pass=$(openssl passwd -6 -salt $(openssl rand -base64 6) "$default_password")
# 写入 newusers 格式
echo "$username:$encrypted_pass:$uid:$gid:$gecos:$homedir:$shell" >> "$output_file"
done
echo "转换完成:$input_file -> $output_file"
}
# 执行转换
convert_ldap_to_newusers "ldap_export.csv" "newusers_import.txt"
# 显示转换结果
echo "转换后的文件内容:"
cat "newusers_import.txt"
# 创建用户
read -p "是否创建这些用户?(y/n): " confirm
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
echo "开始创建用户..."
sudo newusers -m "newusers_import.txt"
# 设置密码策略
echo "设置密码策略..."
for user in $(cut -d: -f1 "newusers_import.txt"); do
sudo chage -d 0 "$user" # 首次登录必须改密码
sudo chage -M 90 "$user" # 密码90天过期
sudo chage -W 7 "$user" # 提前7天警告
echo "已配置用户 $user 的密码策略"
done
echo "用户创建和配置完成!"
fi
# 清理
rm -f ldap_export.csv newusers_import.txt
示例3:学校机房批量创建学生账户
bash
#!/bin/bash
# 学校机房学生账户批量创建
CLASS_NAME="计算机2024级1班"
CLASS_DIR="/home/classes/computer_2024_1"
PASSWORD_FILE="/root/student_passwords.txt"
USER_FILE="/tmp/students_newusers.txt"
# 创建班级目录
sudo mkdir -p "$CLASS_DIR"
# 初始化文件
echo "# $CLASS_NAME 学生账户信息" > "$USER_FILE"
echo "# 生成时间: $(date)" >> "$USER_FILE"
echo "======================================" >> "$USER_FILE"
echo "# $CLASS_NAME 初始密码" > "$PASSWORD_FILE"
echo "# 请妥善保管,分发后立即删除" >> "$PASSWORD_FILE"
echo "======================================" >> "$PASSWORD_FILE"
# 学生名单(实际可以从文件读取)
declare -A students=(
["stu2024001"]="张三"
["stu2024002"]="李四"
["stu2024003"]="王五"
["stu2024004"]="赵六"
["stu2024005"]="钱七"
["stu2024006"]="孙八"
["stu2024007"]="周九"
["stu2024008"]="吴十"
)
# 起始 UID/GID
BASE_UID=3000
counter=0
echo "开始生成学生账户..."
for username in "${!students[@]}"; do
fullname="${students[$username]}"
uid=$((BASE_UID + counter))
gid=$((BASE_UID + counter))
homedir="$CLASS_DIR/$username"
# 生成随机密码(8位,包含大小写字母和数字)
password=$(openssl rand -base64 6 | tr -d '/+' | cut -c1-8)
# 生成加密密码
encrypted_pass=$(openssl passwd -6 -salt $(openssl rand -base64 6) "$password")
# 写入 newusers 文件
echo "$username:$encrypted_pass:$uid:$gid:$fullname:$homedir:/bin/bash" >> "$USER_FILE"
# 保存明文密码(仅用于分发)
echo "用户名: $username ($fullname)" >> "$PASSWORD_FILE"
echo "初始密码: $password" >> "$PASSWORD_FILE"
echo "家目录: $homedir" >> "$PASSWORD_FILE"
echo "---" >> "$PASSWORD_FILE"
((counter++))
done
# 创建用户
echo "正在创建用户账户..."
sudo newusers -m "$USER_FILE"
# 设置目录权限
echo "设置目录权限..."
sudo chmod 755 "$CLASS_DIR"
for username in "${!students[@]}"; do
homedir="$CLASS_DIR/$username"
sudo chown -R "$username:$username" "$homedir"
sudo chmod 700 "$homedir"
done
# 创建共享目录
SHARED_DIR="$CLASS_DIR/shared"
sudo mkdir -p "$SHARED_DIR"
sudo chown :"$CLASS_NAME" "$SHARED_DIR"
sudo chmod 2775 "$SHARED_DIR" # 设置 SGID,保持组权限
# 添加用户到班级组
sudo groupadd "$CLASS_NAME"
for username in "${!students[@]}"; do
sudo usermod -aG "$CLASS_NAME" "$username"
done
echo "======================================"
echo "学生账户创建完成!"
echo "班级: $CLASS_NAME"
echo "学生数量: ${#students[@]}"
echo "班级目录: $CLASS_DIR"
echo "共享目录: $SHARED_DIR"
echo "密码文件: $PASSWORD_FILE"
echo ""
echo "请将密码文件分发给学生后立即删除!"
echo "======================================"
# 显示密码文件内容
echo "生成的密码文件内容:"
cat "$PASSWORD_FILE"
# 清理临时文件
rm -f "$USER_FILE"
⚠️ 重要注意事项
- 权限要求 :必须使用
sudo或 root 权限运行 - 密码安全 :
- 密码在文件中以加密形式存储
- 建议使用强加密算法(SHA-512)
- 创建后立即修改默认密码
- UID/GID 冲突 :
- 确保 UID 和 GID 唯一
- 建议从 1000 开始(普通用户)
- 系统用户 UID < 1000
- 家目录权限 :
- 使用
-m选项自动创建家目录 - 确保家目录权限正确(700)
- 使用
- 用户已存在 :
- 如果用户已存在,
newusers会更新用户信息 - 包括密码、家目录、shell 等都会被更新
- 如果用户已存在,
🔄 与 useradd 命令对比
| 特性 | newusers | useradd |
|---|---|---|
| 批量操作 | 支持批量创建/更新 | 仅支持单个用户 |
| 输入方式 | 从文件读取 | 命令行参数 |
| 执行速度 | 快速批量处理 | 每次调用单独处理 |
| 配置复杂度 | 需要准备文件 | 命令行参数简单 |
| 适用场景 | 大量用户创建 | 单个用户创建 |
| 密码设置 | 文件内加密密码 | 交互式或参数设置 |
🛠️ 故障排查
1. 常见错误及解决
bash
# 错误:用户已存在
# 解决:删除用户或更新用户信息
sudo userdel username
# 或直接更新(newusers 会更新现有用户)
# 错误:UID/GID 冲突
# 解决:检查并分配唯一 UID/GID
getent passwd | grep ":1001:"
getent group | grep ":1001:"
# 错误:无效的 shell
# 解决:确保 shell 路径正确
cat /etc/shells # 查看有效 shell
# 错误:密码加密问题
# 解决:使用正确的加密方法
openssl passwd -6 -salt $(openssl rand -base64 6) "password"
2. 验证创建结果
bash
# 检查用户是否创建成功
id username
finger username
getent passwd username
# 检查家目录
ls -la /home/username
ls -la ~username
# 检查密码是否设置
sudo grep username /etc/shadow
# 测试登录
su - username
# 批量检查所有新用户
for user in $(cut -d: -f1 users.txt); do
if id "$user" &>/dev/null; then
echo "✓ 用户 $user 创建成功"
else
echo "✗ 用户 $user 创建失败"
fi
done
📌 最佳实践
- 备份现有数据 :操作前备份
/etc/passwd、/etc/shadow、/etc/group - 测试环境验证:先在测试环境验证用户文件格式
- 密码策略:创建后强制用户修改初始密码
- 权限管理:正确设置家目录权限(700)
- 日志记录:记录所有批量操作
- 验证结果:创建后验证用户账户信息
🎯 快速参考卡
准备用户文件:
username:encrypted_pass:uid:gid:gecos:homedir:shell
生成加密密码:
openssl passwd -6 -salt $(openssl rand -base64 6) "密码"
基本创建:
sudo newusers users.txt # 创建用户
sudo newusers -m users.txt # 创建用户和家目录
sudo newusers -r users.txt # 创建系统用户
sudo newusers -s users.txt # 使用 SHA-512 加密
批量更新:
sudo newusers update.txt # 更新现有用户
验证结果:
id username # 检查用户
getent passwd username # 检查用户信息
sudo grep username /etc/shadow # 检查密码
ls -la /home/username # 检查家目录
安全建议:
1. 备份 /etc/passwd, /etc/shadow, /etc/group
2. 使用强加密密码(SHA-512)
3. 创建后强制修改初始密码
4. 设置合适的家目录权限(700)
5. 删除明文密码文件
newusers 是系统管理员批量管理用户的强大工具,特别适合需要一次性创建大量用户的场景。正确使用可以大大提高工作效率,但务必注意安全性和数据备份。