有点卡在这里,没有找到任何解决方案。
检查用户是否存在于 /etc/passwd 中,如果存在则创建一个带有前缀 new_the_existed_one 的新用户
#!/bin/bash
myuser="/home/yakyak/Desktop/Exercises/newusers.txt"
sed '/^[ \t]*$/d' $myuser | while read -r line
do
name="$line"
# adduser --disabled-login --gecos "" $name
# check if user exist
isthere=$(cut -d: -f1 /etc/passwd | grep "$name")
# if user was added then make insert record into log file
if [[ "$isthere" == "$name" ]]
then
echo "User already exist, creating new user.."
adduser --disabled-login
# adduser --disabled-login --gecos " " $name
fi
done
答案1
#!/bin/bash
NAME_REGEX='^[a-z][-a-z0-9]*$' # default value for adduser.conf
. /etc/adduser.conf # "source" it in case local config is different
myuser='/home/yakyak/Desktop/Exercises/newusers.txt'
grep "$NAME_REGEX" "$myuser" | while read -r name; do
while getent passwd "$name" > /dev/null; do
name="new_$name"
done
# check if $name is > 32 characters
if [ "${#name}" -gt 32 ] ; then
echo "username '$name' is too long" > /dev/stderr
else
adduser --disabled-login --gecos '' "$name"
fi
done
它不是用来sed
从文件中删除空行newusers.txt
,而是用来grep
排除无效的用户名,即那些不匹配存储在名为 的 shell 变量中的模式$NAME_REGEX
。它使用与自身相同的变量名称(和正则表达式模式)adduser
来定义“有效”。查看man adduser.conf
并搜索NAME_REGEX
.
这将继续在 $name 前面添加“new_”,直到 $name 不存在于 passwd 数据库中。如果“user”存在,它将尝试“new_user”。如果“new_user”存在,它将尝试“new_new_user”。然后是“new_new_new_user”。等等。
该脚本使用getent passwd
,但只关心退出代码 - 输出被丢弃(重定向到 /dev/null)。如果 getent 以 0 (true) 退出,则用户存在,因此请重试。
当getent
返回 false(即$name
不存在)时,它会检查名称是否太长。如果是,它会打印一条错误消息。如果不是,则运行adduser
。
顺便说一句,我们期望从 getent 看到的实际退出代码是0
用户是否已存在以及2
用户是否不存在。在某些情况下,getent 可以返回不同的退出代码(请参阅 参考资料),但对于我们使用 getent 的方式(即搜索数据库并提供用户名)man getent
来说,这是不可能的。passwd
稍微好一点的版本是使用数字后缀作为用户名。例如,printf
与%03i
3 位宽零填充数字的格式字符串一起使用(例如001
、002
等)。如果您不希望它用零填充,请%i
改用。对于处理的每个用户名,该count
变量在外部 while 循环中重置为零。
#!/bin/bash
NAME_REGEX='^[a-z][-a-z0-9]*$' # default value for adduser.conf
. /etc/adduser.conf # "source" it in case local config is different
myuser='/home/yakyak/Desktop/Exercises/newusers.txt'
grep "$NAME_REGEX" "$myuser" | while read -r user; do
name="$user"
count=0
while getent passwd "$name" > /dev/null; do
let count+=1
name="$(printf "%s%03i" "$user" "$count")"
done
# check if $user is > 32 characters
if [ "${#name}" -gt 32 ] ; then
echo "username '$name' is too long" > /dev/stderr
else
adduser --disabled-login --gecos '' "$name"
fi
done
此版本使用两个变量作为用户名 -$user
用于从 newusers.txt 文件中读取的名称,以及$name
用于我们尝试使用的当前用户名。 $name 最初是从 $user 复制的,内部 while 循环通过递增变量$count
并将其附加到$user
返回getent
true 来更新 $name。
最后,以上都不是特别好的脚本。他们所做的只是最低限度的要求。就我个人而言,我倾向于用 perl 而不是 bash 编写它,因为shell中的文本处理是一个PITA。