关于$'\r': command not found错误的一点体会

今天运行一个其他组开发的jar包,这个jar包由于运行参数是通过命令行的方式输入的,所以需要运行一个shell脚本来启动。
启动脚本类似这样:

#!/bin/bash
jdbc_driverClassName=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://XX/XX?characterEncoding=UTF-8
jdbc_username=XX
jdbc_password=XX
java -jar xx.jar ${jdbc_driverClassName} ${jdbc_url} ${jdbc_username} ${jdbc_password}&

但是启动的时候一直报java.lang.ClassNotFoundException: com.mysql.jdbc.Driver,错误在Class.forName(jdbcDriver)这行。

  1. 最开始怀疑是MySQL驱动的问题,首先确认了classpath肯定正确,包括尝试把mysql-connector-java-5.0.2.jar复制到jdk的lib/ext/下,还是不行。
  2. 尝试移除Class.forName这行代码,因为jdbc4(JDK1.6)之后的版本是可以不写Class.forName的。结果开始报下一行的数据库连接用户名密码错误,但是这个用户名密码是没问题的,使用客户端可以正常连上。
  3. 怀疑是启动脚本的问题,尝试写死配置参数(不通过命令行指定),结果。。居然可以了。。由此推断是shell脚本什么地方写错了。
  4. 反复检查shell脚本,没看出什么问题,这才留意到程序启动的时候有报一个./start.sh: line 15: $'\r': command not found,由于后面的错误太多了,被刷屏了所以之前没有注意到。大概猜到是换行符的问题,不过因为这个可以导致数据库连接出错吗?在第一步的时候,我已经有打印输入的参数了。
  5. 打开vi使用set ff=unix解决这个换行符的问题后,重新启动,已经可以跑起来了。但是还是蛮疑惑的,一个换行符有这么大作用吗?
  6. 使用getBytes()方法打印入参的byte数组,结果发现每个参数的后面都跟上了一个ASCII码为13的这个字符,也就是\r回车符。我们知道win下的换行是回车符+换行符,也就是\r\n,而unix下是换行符\n。linux下不识别\r为回车符,所以导致每行的配置都多了个\r。并且因为这个是控制字符,所以在输出参数的时候不会打印出来,只有使用getBytes()才能看到。

至此,问题已经明朗。我觉得一个教训就是,出现错误的时候,一定要先去检查第一行的错误,任何比较微小的问题(比如这种回车符),都可能引起大的问题,而且通过后面的错误信息还不好定位。另外一个就是在win下修改shell脚本的时候,要特别警惕,注意文件的格式。

你可能感兴趣的:(Linux,异常与错误)