【问题标题】:Shell script syntax error: unexpected end of lineShell 脚本语法错误:意外的行尾
【发布时间】:2017-03-28 11:02:52
【问题描述】:

我编写了一个简单的 shell 脚本来检查 xml 文件是否存在,如果存在,则将旧 xml 文件重命名为备份,然后将新 xml 文件移动到旧 xml 文件的存储位置。

#!/bin/sh    

oldFile="/Documents/sampleFolder/sampleFile.xml"
newFile="/Documents/sampleFile.xml"
backupFileName="/Documents/sampleFolder/sampleFile2.backup"
oldFileLocation="/Documents/sampleFolder"

if [ -f "$newFile" ] ; then
    echo "File found"
    #Rename old file
    mv $oldFile $backupFileName
    #move new file to old file's location
    mv $newFile $oldFileLocation
else
    echo "File not found, do nothing"
fi   

但是,每次我尝试运行脚本时,都会收到 4 个未找到命令的消息和语法错误:文件意外结束。关于为什么我得到这些命令未找到错误或文件意外结束的任何建议?我仔细检查了我是否关闭了所有双引号,我有代码突出显示:)

编辑: 运行脚本的输出:

: command not found: 
: command not found: 
: command not found1: 
: command not found6: 
replaceXML.sh: line 26: syntax error: unexpected end of file

【问题讨论】:

  • 你能发布确切的错误信息吗?我认为您的代码没有任何问题。
  • 这在这里工作(使用 bash 和破折号)。但是您可能应该将 mv 上使用的每个变量放在双引号之间。
  • 您的脚本可能有 DOS 行结尾。
  • 学习打开shell调试,这样你就可以看到正在执行的内容。 set -vx。祝你好运。
  • 可能是这样,我在 windows 中创建了 shell 脚本,然后将其复制到我在 VMWare 播放器中的 ubuntu 实例中进行测试。我确实创建了另一个空的 shell 脚本,复制了这些东西,错误就消失了。现在它没有找到文件,但这是另一个问题:)

标签: bash shell cygwin


【解决方案1】:

我相信你在 Cygwin 上运行。错误消息比您看到的更多:

: command not found: 
: command not found: 
: command not found1: 
: command not found6: 
replaceXML.sh: line 26: syntax error: unexpected end of file

您可能使用 Windows 编辑器创建脚本文件,这意味着它使用 Windows 样式的 CR-LF ("\r\n") 行结尾,而不是 Unix 样式的 LF ('\n') 行结尾。 Cygwin 下的一些程序可以处理任何一种形式,但 shell 不能。

例如,看起来像这样的线

then

看起来像贝壳

then^M

其中 ^M 是 ASCII CR 字符。如果它存在,这实际上是一个有效的命令名称,但它不存在,所以 shell 抱怨:

then^M: command not found

但是打印 CR 字符会导致光标返回到行首,因此 : 之前的所有内容都会被覆盖。

您收到“文件意外结束”消息,因为 shell 从未看到与 if 匹配的 fi。

您可以使用dos2unix 命令来修复行尾。请务必阅读手册页 (man dos2unix);与大多数文本过滤器不同,dos2unix 替换其输入文件而不是写入标准输出。

【讨论】:

  • 我什至没有想到 cygwin。很好的答案。
  • 如果你碰巧运行的是ubuntu 10.04,那么就没有dos2unix。相反,您将使用sudo apt-get install tofrodos 安装tofrodos,然后在您的文件上运行fromdos。 (参考:ubuntuforums.org/showthread.php?t=1540180)
【解决方案2】:

我真的看不出你的代码有什么问题,除了旧的 shell 不在合法的地方。还要注意 mv 参数周围的引号(但如果文件命名正确,这应该不是问题)。

试试这个:

#!/bin/sh    

oldFile="/Documents/sampleFolder/sampleFile.xml"
newFile="/Documents/sampleFile.xml"
backupFileName="/Documents/sampleFolder/sampleFile2.backup"
oldFileLocation="/Documents/sampleFolder"

if [ -f "$newFile" ]
then
    echo "File found"
    mv "$oldFile" "$backupFileName"
    mv "$newFile" "$oldFileLocation"
else
    echo "File not found, do nothing"
fi  

PS:验证 /bin/sh 是(或指向)基于 bourne 的 shell。

【讨论】:

    【解决方案3】:

    在我的情况下我做了什么: 我使用Bash On Ubuntu on Windows(在Windows 10)而不是Cygwin,然后使用sudo apt-get install dos2unix安装dos2unix并使用以下命令解决此问题:

    $ dos2unix < compilelibs.sh > output.sh
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多