该shell脚本应该将用户添加到系统中.新用户详细信息位于文件中.shell使用以下消息拒绝此脚本:
syntax error near unexpected token 'done'.
Run Code Online (Sandbox Code Playgroud)
怎么了?
#!/bin/bash
#Purpose: Automatically add new users in a linux system based upon the data found within a text file
# Assign encryped passwords to each user
# Add users to groups or create new groups for these users
# Report errors and successful operations where necessary in log files
# post help options (echo)
#Root validation
if [[ $(id -u) -eq 0 ]]; then
#Argument validation
if [[ -z "$1" ]]; then
echo "No arguments found!"
echo "Please include a user detail text file as first argument"
echo "Please include a report text file as second argument"
echo "Please include an error report text file as the third argument"
echo "Use the -h argument (i.e. ./script -h) for help"
exit 1
fi
#Help validation and Help file
if [[ "$1" = "-h" ]]; then
echo "This is the help information file"
echo "This script is designed to add users to a linux system by reading information from a user detail file (such as userlist.txt)"
echo "The format of this user detail text file is "username password groupname fullname" seperated using TAB spacing"
echo "This script will read the first argument as the user detail file, the second and third arguments will be read as a success report file and error report file respectively"
exit
fi
#Reads first argument as user detail file for data
cat userlist.txt | while read uname password gname fullname
#Reads /etc/passwd for Username
egrep -w "^$uname" /etc/passwd
#If Username is found then error reports
if [ $? == 0 ]; then
echo "User Already Exists : Error adding user with username $uname;$gname;$fullname" >> Successes1.log
exit 1
else
#Reads /etc/group for Groupname
egrep -w "^$gname" /etc/group
#If Groupname is found then nothing
if [ $? == 0 ]; then
echo ""
else
#If Groupname not found then creates new group and reports
groupadd "$gname"
echo "Group Not Found: New Group $gname was created" >> Successes1.log
fi
#Retrieves Date
createddate=$(date)
#Perl password script takes input from Userlist
pass=$(perl -e 'print crypt($ARGV[0], "Password")' "$password")
#Adds Users with variables from userlist
useradd "$uname" -g "$gname" -c "$fullname" -p "$pass"
#Reports information to successlist and errorlist report files
if [ $? == 0 ]; then
groupid=$(id -g $uname)
userid=$(id -u $uname)
echo "User Successfully Added: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Successes1.log
else
groupid=$(id -g $uname)
userid=$(id -u $uname)
echo "Useradd Error Occurred: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Errors1.log
echo "Error: Must be root user to execute script"
exit
fi
done
Run Code Online (Sandbox Code Playgroud)
使用答案中的一些想法,我想出了第二次尝试:
#!/bin/bash
#Purpose: Automatically add new users in a linux system based upon the data found within a text file
# Assign encryped passwords to each user
# Add users to groups or create new groups for these users
# Report errors and successful operations where necessary in log files
# post help options (echo)
#Root validation
if [[ $(id -u) -eq 0 ]]; then
#Argument validation
if [[ -z "$1" ]]; then
echo "Usage: $0 usernames report errors" 1>&2
echo "Please include a user detail text file as first argument"
echo "Please include a report text file as second argument"
echo "Please include an error report text file as the third argument"
echo "Use the -h argument (i.e. ./script -h) for help"
exit 1
fi
fi
#Help validation and Help file
if [[ "$1" = "-h" ]]; then
echo "This is the help information file"
echo "This script is designed to add users to a linux system by reading information from a user detail file (such as userlist.txt)"
echo "The format of this user detail text file is "username password groupname fullname" seperated using TAB spacing"
echo "This script will read the first argument as the user detail file, the second and third arguments will be read as a success report file and error report file respectively"
exit
fi
#Reads first argument as user detail file for data
cat jan.txt | while read uname password gname fullname; do
#Reads /etc/passwd for Username
egrep -w "^$uname:" /etc/passwd >/dev/null 2>&1
#If Username is found then error reports
if [ $? == 0 ]
then
echo "User Already Exists : Error adding user with username $uname;$gname;$fullname" >> Errors1.log
else
#Reads /etc/group for Groupname
egrep -w "^$gname" /etc/group
#If Groupname is found then nothing
if [ $? == 0 ]; then
echo ""
else
#If Groupname not found then creates new group and reports
groupadd "$gname"
echo "Group Not Found: New Group $gname was created" >> Successes1.log
done < $1
#Retrieves Date
createddate=$(date)
#Perl password script takes input from Userlist
pass=$(perl -e 'print crypt($ARGV[0], "Password")' "$password")
#Adds Users with variables from userlist
useradd "$uname" -g "$gname" -c "$fullname" -p "$pass"
#Reports information to successlist and errorlist report files
if [ $? == 0 ]
then
groupid=$(id -g $uname)
userid=$(id -u $uname)
echo "User Successfully Added: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Successes1.log
else
groupid=$(id -g $uname)
userid=$(id -u $uname)
echo "Useradd Error Occurred: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Errors1.log
echo "Error: Must be root user to execute script"
exit 1
fi
fi
done
Run Code Online (Sandbox Code Playgroud)
这似乎也不正常.现在怎么了?似乎显示参数和运行但是没有添加用户或组,因此没有创建任何日志
该if起动:
if [ $? == 0 ]; then
echo "User Already Exists : Error adding user with username ...
exit 1
else
Run Code Online (Sandbox Code Playgroud)
以done而不是fi需要而不是结束.
该while循环开始几早期行:
cat userlist.txt | while read uname password gname fullname
Run Code Online (Sandbox Code Playgroud)
缺少它do(另一个错误); 如果它存在,那么它也需要done在最后.有人忘记了缩进.(每级使用2个字符优于0或1,但如果每个级别使用4个空格,则更容易跟踪级别.)请注意,shell没有do因为语法缺乏而抱怨缺少循环是:
while cmd1
cmd2
cmd3 ...
do
Run Code Online (Sandbox Code Playgroud)
就shell而言,它仍在处理列表中的命令cmd1, cmd2, cmd3, ....
这是一个半体面缩进版本的脚本.fi脚本顶部也有一个缺失.
#!/bin/bash
#Purpose: Automatically add new users in a linux system based upon the data found within a text file
# Assign encryped passwords to each user
# Add users to groups or create new groups for these users
# Report errors and successful operations where necessary in log files
# post help options (echo)
#Root validation
if [[ $(id -u) -eq 0 ]]
then
#Argument validation
if [[ -z "$1" ]]
then
echo "No arguments found!"
echo "Please include a user detail text file as first argument"
echo "Please include a report text file as second argument"
echo "Please include an error report text file as the third argument"
echo "Use the -h argument (i.e. ./script -h) for help"
exit 1
fi
fi
#Help validation and Help file
if [[ "$1" = "-h" ]]
then
echo "This is the help information file"
echo "This script is designed to add users to a linux system by reading information from a user detail file (such as userlist.txt)"
echo "The format of this user detail text file is "username password groupname fullname" seperated using TAB spacing"
echo "This script will read the first argument as the user detail file, the second and third arguments will be read as a success report file and error report file respectively"
exit
fi
#Reads first argument as user detail file for data
cat userlist.txt | while read uname password gname fullname
do
#Reads /etc/passwd for Username
egrep -w "^$uname" /etc/passwd
#If Username is found then error reports
if [ $? == 0 ]
then
echo "User Already Exists : Error adding user with username $uname;$gname;$fullname" >> Successes1.log
exit 1
else
#Reads /etc/group for Groupname
egrep -w "^$gname" /etc/group
#If Groupname is found then nothing
if [ $? == 0 ]
then
echo ""
else
#If Groupname not found then creates new group and reports
groupadd "$gname"
echo "Group Not Found: New Group $gname was created" >> Successes1.log
fi
#Retrieves Date
createddate=$(date)
#Perl password script takes input from Userlist
pass=$(perl -e 'print crypt($ARGV[0], "Password")' $pass)
#Adds Users with variables from userlist
useradd "$uname" -g "$gname" -c "$fullname" -p "$pass"
#Reports information to successlist and errorlist report files
if [ $? == 0 ]
then
groupid=$(id -g $uname)
userid=$(id -u $uname)
echo "User Successfully Added: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Successes1.log
else
groupid=$(id -g $uname)
userid=$(id -u $uname)
echo "Useradd Error Occurred: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Errors1.log
echo "Error: Must be root user to execute script"
exit
fi
fi
done
Run Code Online (Sandbox Code Playgroud)
仍有很大的改进空间.如果用户不是root用户,则应退出根验证块; 相反,它发生在循环内的一英里处.您可以更好地检查参数的数量:$#为您提供参数的数量.如果我尝试过yourscript.sh '' arg2 arg3,你会声称没有参数,实际上问题$1是存在但是是一个空字符串.报告如何使用命令的标准约定如下:
echo "Usage: $0 usernames report errors" 1>&2
Run Code Online (Sandbox Code Playgroud)
这将报告命令的名称和预期的参数.在1>&2将消息发送到标准错误而不是标准输出.这里的逻辑有点奇怪.您检查用户是否为root,然后检查是否存在参数.如果用户不是root用户,则不检查参数.我提交的并不完全合理.
我们可以辩论UUOC(无用的猫).实际上有一个奖项; 我不认为这符合条件.但是,有可能写:
while read uname password gname fullname
do
...
done < $1
Run Code Online (Sandbox Code Playgroud)
嗯...脚本应该采用指定用户的文件名参数,但是cat采用固定的文件名,而不是文件名参数!
同样,论点2和3被刻意忽略; 日志文件是硬编码的.
egrep -w "^$uname" /etc/passwd
#If Username is found then error reports
if [ $? == 0 ]
Run Code Online (Sandbox Code Playgroud)
这个片段可以通过几种方式改进:
if egrep -w "^$uname:" /etc/passwd >/dev/null 2>&1
then
#If Username is found then error report
Run Code Online (Sandbox Code Playgroud)
这egrep直接测试命令的退出状态; 它还可以防止新用户roo因用户而被视为预先存在root.它发送输出和错误输出,/dev/null以便在用户存在时您将看不到任何内容.
最好不要在找到用户名时退出; 你至少可以尝试处理下一个条目.用户存在的报告(终止处理)的记录也是奇数,Successes1.log而不是记录在Errors1.log; 它被视为一个错误.
组检查结构类似,应该进行类似的升级.
你$password用read线读了密码; 但是,在创建密码方面,您有:
pass=$(perl -e 'print crypt($ARGV[0], "Password")' $pass)
Run Code Online (Sandbox Code Playgroud)
在第一个周期,$pass是空的(最有可能); 你应该在最后使用$password双引号:
pass=$(perl -e 'print crypt($ARGV[0], "Password")' "$password")
Run Code Online (Sandbox Code Playgroud)
与egrep命令一样,您也可以useradd直接检查命令的状态.说这是一个if [ $? == 0 ]tyro的标志有点扫地,但事实并非如此.
exit脚本中的最后一个应该是exit 1指示错误退出.如前所述,这之前是关于"你必须是root"的评论,即使在顶部检查了root权限.
警告:我没有尝试过运行脚本; 我很容易错过一些问题.然而,它确实通过了sh -v -n,因此没有留下严重的语法错误.
一旦shell脚本在语法上正确,那么你通常使用sh -x script(或者,如果它接受参数sh -x script arg1 arg2 arg3 ...)调试它.这是执行跟踪模式.shell或多或少地告诉你,它正在做什么.信息写入标准错误.如果您愿意,您甚至可以捕获输出以供日后审查:
sh -x script arg1 arg2 arg3 2>script-x.log
Run Code Online (Sandbox Code Playgroud)
该2>script-x.log符号将标准错误的文件script-x.log(选择自己有意义的名字;我经常使用x或xxx用于文件,我不会想保留,但我也删除这些文件,而不必甚至看着他们,因为我知道他们是一次性的文件) .