关于报错“syntax error near unexpected token `”和回车换行

来源:互联网 发布:java工程师简历 编辑:程序博客网 时间:2024/06/09 16:52

本来是很简单一个事情,转过来是因为打字机这事比较有趣……

http://blog.csdn.net/xyp84/archive/2009/08/11/4435899.aspx

 

摘要一下:

 

回车

换行

0D

0A

<CR>

<LF>

Carriage Return

Line Feed

 

 

“/r”

“/n”

win32

0D

0D 0A

unix

0D

0A

 

============淡定的分割线===============

 

今天写了个shell脚本,在自己机器上运行正常,给同事,运行报错syntax error near unexpected token `,左看右看shell脚本没有问题,没有办法google搜索,发现一位仁兄讲的挺好,内容如下:

      用命令vi -b 打开你的SHELL脚本文件,你会。发现每行脚本最后多了个^M。

  那么接下来就要搞清楚这个^M是什么东东?

  long long ago.....  老式的电传打字机使用两个字符来另起新行。一个字符把滑动架移回首位 (称为回车,<CR>,ASCII码为0D),另一个字符把纸上移一行 (称为换行, <LF>,ASCII码为0A)。当计算机问世以后,存储器曾经非常昂贵。有些人就认定没必要用两个字符来表示行尾。UNIX 开发者决定他们可以用 一个字符来表示行尾,Linux沿袭Unix,也是<LF>。Apple 开发者规定了用<CR>。开发 MS-DOS以及Windows 的那些家伙则决定沿用老式的<CR><LF>。

  因为MS-DOS及Windows是回车+换行来表示换行,因此在Linux下用Vim查看在Windows下用VC写的代码,行尾后的“^M”符号,表示的是符。

  在Vim中解决这个问题,很简单,在Vim中利用替换功能就可以将“^M”都干掉,键入如下替换命令行:

  1)vi -b setup.sh

  2)在命令编辑行<就是: 按ESC键 然后shift+:冒号>输入:%s/^M//g

  注意:上述命令行中的“^M”符,不是“^”再加上“M”,而是由“Ctrl+v”、“Ctrl+M”键生成的。

  这样替换掉以后,保存就可以执行了。当然还有其他的替换方式比如:

  a.一些linux版本有 dos2unix 程序,可以用来祛除^M。

  b.cat filename1 | tr -d "/r" > newfile 去掉^M生成一个新文件,还有sed命令等,凡是可以替换的命令都是可以用来新生成一个文件的。

      按照上面所说的,删除^Mshell脚本就运行正常,后来问同事,原来他windows记事本中修改了程序路径,导致每一行多出了^M。




我运行这段代码出现了错误,不知道怎么处理,好像是括号的问题代码如下:#!/bin/bash#program:#    using netstat and grep to detect www servicesPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHtesting=$ (netstat -tuln |grep ":80 ")if [ "$testing" !="" ];then     echo "www is running in your system."fi我试着调了一下,换成了下面的代码就好使了,但不知道为什么,求解答!改完的代码是:#!/bin/bash#program:#    using netstat and grep to detect www servicesPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHtesting=$ \netstat -tuln |grep ":80 "\)if [ "$testing" !="" ];then     echo "www is running in your system."fi



清木,我想告诉你,你完善后的代码,比你完善之前错得更多。当然,也不是大错。
  假设你完善后的脚本名为test2.sh
  执行 bash -x  test2.sh
  你会发现testing=$ \netstat -tuln |grep ":80 "\)这一句,实际执行为
  + testing='$'
  + netstat -tuln
  + grep ':80 )'
  也就是说,这句命令在shell看来,一行命令变成了两部分:
  testing=$
  netstat -tuln |grep ":80 "\)’    #注意,这里grep 查找的是 :80 )而非:80
  最终,赋给testing的值不是 netstat -tuln |grep ":80 " 的输出结果。
  
  你会问我修改后的脚本为什么不报之前的错误。这是因为bash允许在同一行给多个变量
  赋值。它们在被解释时,被分作多行,分别执行。
  \n, \是bash中的转义字符 \n代表的就是n,所以\netstat就是netstat
  综上,testing=$ \netstat -tuln |grep ":80 "\) 等效于:
  testing=$
  netstat -tuln |grep ":80 )"
  两行命令都没有语法错误,所以不会报错。当然,这也与你的本意不符。
  
  你最初的脚本有两处错误
    1. testing=$ (netstat -tuln |grep ":80 ")
    $与左括号之间不能有空格
  等效命令:
  testing=`etstat -tuln |grep ":80 "`        
  # ` 在键盘上感叹号按键的左边,有波浪号的按键上
  
  2. if "$testing" !="" ];then
  等号与双引号之间有空格
  推荐的写法:
  if "x$testing" != "x" ];then            
  #防止变量为空时,出现错误。你的写法因为加上了双引号,也是不会出错的。

0 0