此shell脚本应该将用户添加到系统中。新用户详细信息位于文件中。 shell使用以下消息拒绝此脚本:
syntax error near unexpected token 'done'.
怎么了?
#!/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
使用答案中的一些想法,我想出了第二次尝试:
#!/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
这似乎也不正常。现在怎么了? 似乎显示参数和运行但是没有添加用户或组,因此没有创建日志
答案 0 :(得分:5)
if
从:
if [ $? == 0 ]; then
echo "User Already Exists : Error adding user with username ...
exit 1
else
以done
而不是所需的fi
结束。
while
循环早先开始几行:
cat userlist.txt | while read uname password gname fullname
缺少do
(另一个错误);如果存在,那么最后还需要done
。有人忘记了缩进。 (每个级别使用2个字符优于0或1,但如果每个级别使用4个空格,则更容易跟踪级别。)请注意,shell没有抱怨缺少do
,因为while循环的语法是:
while cmd1
cmd2
cmd3 ...
do
就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
仍有很大的改进空间。如果用户不是root用户,则应退出根验证块;相反,它发生在循环内的一英里处。您可以更好地检查参数的数量:$#
为您提供参数的数量。如果我尝试yourscript.sh '' arg2 arg3
,你会声称没有参数,实际上问题是$1
存在但是是一个空字符串。报告如何使用命令的标准约定如下:
echo "Usage: $0 usernames report errors" 1>&2
报告命令的名称和预期的参数。 1>&2
将消息发送到标准错误而不是标准输出。这里的逻辑有点奇怪,即便如此。您检查用户是否为root,然后检查是否存在参数。如果用户不是root用户,则不检查参数。我提交并不完全合理。
我们可以辩论UUOC(无用的猫)。实际上有一个奖项;我不认为这符合条件。但是,可以写:
while read uname password gname fullname
do
...
done < $1
嗯......脚本应该采用指定用户的文件名参数,但cat
采用固定文件名,而不是文件名参数!
同样,论点2和3被刻意忽略;日志文件是硬编码的。
egrep -w "^$uname" /etc/passwd
#If Username is found then error reports
if [ $? == 0 ]
这个片段可以通过以下几种方式进行改进:
if egrep -w "^$uname:" /etc/passwd >/dev/null 2>&1
then
#If Username is found then error report
直接测试egrep
命令的退出状态;它还会阻止新用户roo
因用户root
而被视为预先存在。它将输出和错误输出发送到/dev/null
,这样当用户存在时您将看不到任何内容。
最好不要在找到用户名时退出;你至少可以尝试处理下一个条目。用户存在的报告(终止处理)也记录在Successes1.log
而不是Errors1.log
中,这也很奇怪;它被视为错误。
组检查结构类似,应该进行类似的升级。
您使用$password
行将密码读入read
;但是,在创建密码方面,你有:
pass=$(perl -e 'print crypt($ARGV[0], "Password")' $pass)
在第一个周期,$pass
为空(最有可能);你最后应该在双引号中使用$password
:
pass=$(perl -e 'print crypt($ARGV[0], "Password")' "$password")
与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
2>script-x.log
表示法将标准错误发送到文件script-x.log
(选择您自己有意义的名称;我经常使用x
或xxx
来查找我不想要的文件保持,但我也删除这些文件,甚至没有看到它们,因为我知道它们是一次性文件。)
答案 1 :(得分:0)
“完成”应该与之前的“做”配对 它不是你脚本的结尾。
答案 2 :(得分:0)
您的while
缺少do
:
cat userlist.txt | while read uname password gname fullname
do
或
cat userlist.txt | while read uname password gname fullname; do