从CSV批量创建Linux用户的Bash脚本运行异常求助
批量创建Linux用户脚本异常排查
我编写了一个从CSV文件批量创建Linux用户的Bash脚本,但运行后出现异常:仅创建了一个用户,且用户名与CSV文件内容不符。以下是我的CSV文件内容及脚本代码,请协助排查问题:
CSV文件内容
Id,Prenom,Nom,Mdp,Rôle 1001,Octavia,Blake,U9nh4W,User 1002,Bellamy,Blake,2Nn2Ja,Admin 1003,Abigail ,Griffin,v8G2Zc,User 1004,Finn,Collins,N98rqT,User 1005,Jasper,Jordan,8Ltk4R,User 1006,Raven,Reyes,n45RQz,Admin 1007,Monty ,Green,Y3yzP4,User 1008,Clarke,Griffin,f56SxP,Admin 1009,Marcus,Jane,bNw4T9,User 1010,John ,Murphy,zT5fH2,User 1011,Wells,Jaha,z4b5RJ,User 1012,Maddy ,Griffin,9jqW9F,Admin
原脚本代码
#!/usr/bin/bash Ajua_input="/home/sofiane/Téléchargements/Shell_Userlist.csv" declare -a Id declare -a Prenom declare -a Nom declare -a Mdp declare -a Role while IFS=, read -r Id Prenom Nom Mdp Role; do Id+=("$Id") Prenom+=("$Prenom") Nom+=("$Nom") Mdp+=("$Mdp") Role+=("$Role") done<$Ajua_input for index in "${!username[@]}"; do sudo groupadd "${role[$index]}"; sudo useradd -g "${role[$index]}" \ -d "/home/${username[index]}" \ -s "/bin/bash" \ -p "$(echo "${pass[$index]}" | openssh passwd -1 -stdin)" "${username[$index]}" done
问题排查与修复
1. 数组与变量名称不匹配(核心问题)
- 原脚本定义的数组是
Prenom、Nom、Mdp、Role,但循环时错误使用了未定义的username、pass、role数组,导致实际仅能获取到最后一次循环的变量值,甚至因为数组不存在出现异常。 - 同时,
while循环中的变量名与数组名重名(如Id既是普通变量又是数组名),会导致数组赋值混乱。 - 解决方案:统一变量名,将用户名定义为
Prenom和Nom的拼接,并修正数组引用名称。
2. 未跳过CSV表头
- 原脚本会读取第一行表头(
Id,Prenom,...)并尝试创建用户,这就是那个错误用户名的来源。 - 解决方案:使用
tail -n +2跳过第一行再读取。
3. 密码加密命令错误
- 原脚本使用
openssh passwd,正确命令应为openssl passwd,且参数格式需正确。 - 解决方案:修正为
openssl passwd -1 -stdin。
4. 重复创建组
- 每次循环都执行
groupadd,若组已存在会报错。 - 解决方案:先判断组是否存在,不存在再创建:
if ! getent group "$role" > /dev/null; then sudo groupadd "$role"; fi。
5. 字段空格处理
- CSV中部分字段末尾有空格(如
Abigail),会导致用户名或组名带空格,需去除。 - 解决方案:使用
xargs去除字段前后空格。
6. 变量大小写不一致
- Bash变量区分大小写,原脚本数组是
Role,循环时用role,导致取值为空。 - 解决方案:统一大小写,比如都用小写
role。
修复后的脚本
#!/usr/bin/bash Ajua_input="/home/sofiane/Téléchargements/Shell_Userlist.csv" # 跳过表头,逐行处理CSV tail -n +2 "$Ajua_input" | while IFS=, read -r id prenom nom mdp role; do # 去除字段前后空格 prenom=$(echo "$prenom" | xargs) nom=$(echo "$nom" | xargs) role=$(echo "$role" | xargs) mdp=$(echo "$mdp" | xargs) # 生成用户名:名全小写.姓全小写,可根据需求调整格式 username="${prenom,,}.${nom,,}" # 创建组(如果不存在) if ! getent group "$role" > /dev/null; then sudo groupadd "$role" fi # 加密密码 encrypted_pass=$(echo "$mdp" | openssl passwd -1 -stdin) # 创建用户 sudo useradd -g "$role" \ -d "/home/$username" \ -s "/bin/bash" \ -p "$encrypted_pass" \ "$username" echo "已创建用户:$username" done
说明
- 用户名格式采用
小写名.小写姓,可根据需求修改(比如改为首字母小写+姓全小写:${prenom:0:1,,}${nom,,})。 - 执行脚本时需确保有sudo权限,且
openssl已安装(可通过apt install openssl或yum install openssl安装)。
内容的提问来源于stack exchange,提问作者sofiane-benali
相关产品推荐
相关产品推荐

