从一个shell脚本执行出错聊起

 

运维人员面对的环境是复杂的。仅就操作系统而言,就有Windows ServerUnixAIX和各种分支服务器OS。由于系统环境的差异,运维人员是很难做到知识面面俱到,对所有的特性了如指掌。这个时候,个人发展的方向性和坚持精神就十分重要。一点点的积累,从一些小问题着手,个人才能慢慢的成长。

AIX/LinuxWindows在体系架构、文件系统等方面的差异多如牛毛。本篇从一个执行错误的shell脚本入手,讨论一个简单的文本差异特性。

 

1、问题出现

 

一个同事在编写备份Shell脚本时,遇到了报错信息如下。

 

bb

 

报错是比较奇怪的。脚本命令是参考现成执行脚本编写的,不会有过多的语法语义错误。更有甚者,一些报错行(如2226)脚本中都是空行。空行为什么会出现报错信息?

 

2、文本结尾差异

 

这种情况,通常是遇到了文本行结尾差异问题。ASCII格式是我们非常常用的格式类型。从Linux中大量配置文件,到各类型应用系统的日志文件,我们都可以看到ASCII格式文本的身影。

经常使用AIX/Unix环境的朋友可能会有这样的经历:如果我们将AIX/Unix环境创建的文件传递到Windows平台,使用“记事本”软件打开,就会发现所有的换行标记都转化为黑点,而且换行数据全部被设定为一行。

解决这种混乱,比较好的方法是使用专业的工具如UlterEdit或者写字板打开,换行标记可以识别正确。

究其原因,本质上是由于两种操作系统平台对于换行标记差异造成的。Unix/AIX中,换行标记是Line Feed(也就是经常出现的LF)。而在Windows环境中,换行回车标记为一个Line Feed外加一个Carriage ReturnCR)。无论是LF还是CR,都反映在ASCII格式的文件字符中。

在很多情况下,换行字符是文件进行跨平台经常出故障的地方。如果我们在Windows环境下保存一个文本文件,那么拿到AIX/Unix环境下,读取过程就会出现一个多余的^M字符,从而报错。这也就是同事遇到问题的本质原因。

经过询问,同事脚本的确进行过Windows环境的编辑保存动作。并且是使用默认的记事本报错。

那么,如何处理这样的问题呢?

 

3Utl_File输出的文件回车符

 

聊解决办法之前,我们先看看PL/SQL程序包utl_file。程序UTL_FILE历史很久,可以追溯到早期的Oracle版本。UTL_FILE用于在Server端指定目录上输出ASCII格式文本。其性能和简单特性给很多应用程序提供了文件输出接口。

那么,Utl_file在换行符问题上,是如何处理的呢?Oracle这里采用的策略是“随行就市”。不同的操作系统平台,put_line的时候生成不同换行标记。下面我们做一个小实验,来证明这点。实验Oracle 11gR2测试。

 

SQL> select * from v$version;

BANNER

----------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production

PL/SQL Release 11.2.0.3.0 - Production

CORE 11.2.0.3.0 Production

TNS for Linux: Version 11.2.0.3.0 - Production

NLSRTL Version 11.2.0.3.0 – Production

 

创建directoryPL/SQL脚本片段。

 

SQL> create directory file_dir as '/tmp';

Directory created

 

SQL> declare

  2    file_info utl_file.file_type;

  3  begin

  4    file_info := utl_file.fopen('FILE_DIR','test.log','w');

  5    utl_file.put_line(file_info,'This is line 1');

  6    utl_file.put_line(file_info,'This is line 2');

  7    utl_file.put_line(file_info,'This is line 3');

  8    utl_file.fclose(file_info);

  9  end;

 10  /

PL/SQL procedure successfully completed

 

Linux环境中,我们可以看到正确的换行数据。

 

[oracle@SimpleLinux tmp]$ pwd

/tmp

[oracle@SimpleLinux tmp]$ ls -l | grep test

-rw-r--r-- 1 oracle oinstall   45 Jan 10 10:52 test.log

[oracle@SimpleLinux tmp]$ cat test.log

This is line 1

This is line 2

This is line 3

 

但是我们使用FTP/SFTP将原来文件下载到Windows本地,使用记事本软件打开文本,发现换行符问题。

 

bb

 

说明,utl_file输出文件的时候,是按照Server端的环境配置来设置换行信息的。如果我们在Windows服务器上执行,想必也是Windows的换行方式。

这也引起了一个问题,我们使用utl_file包生成接口文件,是在一定的操作系统平台基础上。如果是Linux/AIX生成的文件,那么接收方一定也要是Linux/AIX环境才能正确接受。注意:一些文献中声称使用ASCII格式FTP传输文件,可以实现换行符的自动切换。这样是比较方便的,但是笔者没有测试成功。

Windows平台上,遇到这样的问题,我们是使用UltreEdit等编辑器软件保存为Unix换行标记才行。在Linux平台上,有一些命令可以帮助我们这种转换。

 

4unix2dosdos2unix

 

Linux中,特别提供了配对命令工具unix2dosdos2unix,用于进行两种格式的转换。

Unix2dos用于将Unix格式转化为Windows格式,其中的回车符也是支持转换的。使用我们之前创建的test.log文件。

 

[oracle@SimpleLinux tmp]$ unix2dos test.log

unix2dos: converting file test.log to DOS format ...

 

换行符正常,拷贝到Windows环境中查看。

 

bb

 

同理dos2unix可以实现从dos格式转化为unix。针对我们的程序脚本,进行处理。

 

[oracle@SimpleLinux tmp]$ dos2unix hot_xxx_change2.sh

dos2unix: converting file hot_xxx_change2.sh to UNIX format ...

[oracle@SimpleLinux tmp]$

 

windows环境上,我们可以看到这种变化。

 

bb

 

试验成功。

 

5、结论

 

字符集是无论运维还是开发都不容易处理、而且不能避免的老问题。通过这个案例,我们了解了Oracle和操作系统回车字符的特点和功能差异,记录下来,供有需要的朋友不时之需。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-1070126/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/17203031/viewspace-1070126/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值