批处理脚本错误 - 意外的文件结束

时间:2017-03-14 17:00:30

标签: bash batch-file

我试图运行一个任务,我有一个脚本,可以通过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>

1 个答案:

答案 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

我会在您检查退出状态的所有地方使用相同的格式:egrepuseraddchpasswd和{{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;可以选择使用不同的用户名再次尝试。)