我试图运行一个任务,我有一个脚本,可以通过ssh将用户添加到远程服务器。
这是我的代码:
@echo off
setlocal enabledelayedexpansion
set username=%1
set password=%2
for /F "tokens=*" %%a in (Linuxhosts.txt) do (
ssh -i svcaccount_id_rsa svcaccount@%%a 'bash -s' < adduser.txt
)
以下是adduser.txt文件的内容
#!/bin/bash
#========================================================================================================
# This script allows for account creation on a server |
# It also performs error handling to ensure that the user doesn't currently exist on the system. |
# Also provides feedback from the input to verify the entries are correct. |
#========================================================================================================
while true; do
echo -n "Enter username: "
read -r username
/bin/egrep -i "^${username}:" /etc/passwd
if [ $? -eq 0 ]; then
echo "User $username already exists. Please check the username and try again."
else
echo "User $username does not exist. Proceed with account creation."
break
fi
done
adduser "$username"
if [ $? -gt 0 ]; then
echo "Error encountered."
exit 1
fi
echo -n "Enter password: "
read -r -s password
echo "$username:$password" | chpasswd
echo "Password was succesfully set for $username."
if [ $? -gt 0 ]; then
echo "Error encountered. There was a problem with your entry. Please re-run the script and try again."
exit 1
fi
usermod -a -G wheel "$username"
echo "User was succesfully added to the group wheel."
if [ $? -gt 0 ]; then
echo "Error encountered."
exit 1
fi
echo "Successfully added $username to the system."
但是,当我尝试通过cmd提示符运行第一组代码时,出现以下错误:
bash:第41行:语法错误:意外的文件结尾
我不确定我错过了什么。我用另一个名为hello.txt的文件对它进行了测试,运行正常,所以我想知道是否存在我可以看到的间距问题,因为它是一个文本文件。 / p>
答案 0 :(得分:1)
我很确定这里的当前问题是文件adduser.txt是DOS / Windows格式,其行以回车符结束,后跟换行符。 Unix(包括bash)只需要换行作为行终止符,因此将回车视为行的文本的一部分。在这种情况下,这意味着bash看到第17行,&#34;完成&#34;,作为&#34;完成[回车]&#34;这不是一个有效的关键字,并没有结束while
循环,所以它一直在寻找&#34;完成&#34;关键字...直到文件用完为止。
(感谢Squashman在评论中提出这一建议。)
您可能会将此问题从Windows转移到unix;遗憾的是,可用于解决问题的工具差别很大,具体取决于您使用的操作系统等。
顺便说一下,我在这里看到了其他一些问题。首先,脚本中的read
命令将尝试从bash正在读取命令的相同源(即adduser.txt文件)中读取。所以,当它发生时read -r username
它实际上将从脚本文件中读取更晚的行,而不是从运行批处理脚本的用户那里读取。这将很难解决你的做法;我认为将脚本文件实际复制到unix系统会更好,然后单独运行。
此外,正如Socowi在评论中指出的那样,$?
获取最后执行的命令的退出状态,因此在以下部分中:
echo "$username:$password" | chpasswd
echo "Password was succesfully set for $username."
if [ $? -gt 0 ]; then
...
if
条件检查命令echo "Password was succesfully set for $username."
的退出状态,而不是chpasswd
命令。稍后同样的问题适用于usermod
命令。更好的方法是使用您想要检查成功的命令直接作为if
条件:
if echo "$username:$password" | chpasswd; then
echo "Password was succesfully set for $username."
else
echo "Error encountered. There was a problem with your entry. Please re-run the script and try again."
exit 1
fi
我会在您检查退出状态的所有地方使用相同的格式:egrep
,useradd
,chpasswd
和{{1} }命令。
[更新]经过一段时间的考虑,我有几个可能的解决方案:首先,为了解决回车问题,你可以通过usermod
管道文件作为一个快速脏的CR去除器(虽然您可能需要使用引号和/或转义来通过批处理和bash的命令处理获得tr -d "\r"
。其次,将用户名和密码作为参数传递给脚本,而不是让它们读取它们。因此,您的批处理脚本将使用以下内容:
\r
...然后更改adduser.txt以使用ssh -i svcaccount_id_rsa svcaccount@%%a 'tr -d "\r" | bash -s "username" "password"' < adduser.txt
而不是username="$1"; password="$2"
命令(并将read
循环更改为while
,因为它不会&# 39;可以选择使用不同的用户名再次尝试。)