You need to enable JavaScript to run this app. 重定向Informix的dbaccess导出输出时出现字符丢失问题
优惠活动
大模型
产品
解决方案
定价
更多

重定向Informix的dbaccess导出输出时出现字符丢失问题

Informix dbaccess导出到stdout时重定向丢字符问题

问题现象

我在通过dbaccess可执行程序导出Informix数据库的数据时遇到异常,具体测试现象如下:
直接输出到终端时结果正常:

~ # echo "unload to /dev/stdout [ select statement ]" |  dbaccess db 2>/dev/null
H300|1|

通过管道传给hexdump查看也能得到完整结果:

~ # echo "unload to /dev/stdout [ select statement ]" |  dbaccess db 2>/dev/null  | hexdump -C
00000000  48 33 30 30 7c 31 7c 0a  0a                       |H300|1|..|
00000009

但直接重定向到文件时,首字符H丢失,头部多了一个换行:

~ # echo "unload to /dev/stdout [ select statement ]" |  dbaccess db 2>/dev/null > redir
~ # cat redir

300|1|
~ # hexdump -C redir
00000000  0a 33 30 30 7c 31 7c 0a                           |.300|1|.|
00000008

如果将unload目标指定为stdout之外的普通文件,输出完全正常:

~ # cat not_stdout
H300|1|
~ # hexdump -C not_stdout
00000000  48 33 30 30 7c 31 7c 0a                           |H300|1|.|
00000008

另外还有一个特殊现象:如果输出通过gzip -c压缩后再重定向,解压后的结果完整无丢失,符合预期。

环境信息

数据库版本

~ # echo "SELECT DBINFO('version', 'full') FROM \"informix\".systables WHERE tabid = 1" | dbaccess sysuser

Database selected.



(constant)

IBM Informix Dynamic Server Version 11.50.FC9W3

1 row(s) retrieved.



Database closed.

~ # dbaccess -version
Program Name:   dbaccess
Build Version:  11.50.FC9W3
Build Number:   N014
Build Host:     vidar
Build OS:       Linux 2.6.9-34.ELsmp
Build Date:     Fri Mar 29 08:40:42 CDT 2013
GLS Version:    glslib-4.50.FC12
~ # dbaccess -V
DB-Access Version 11.50.FC9W3 Software Serial Number AAA#B000000

复现操作系统

  • SUSE Linux Enterprise 15 x86_64,内核版本5.3.18-22-default
  • SUSE Linux Enterprise Server 11 SP4 x86_64,内核版本3.0.101-63-default

目前已经可以通过cat/tee中转、或者gzip -c处理的方式规避问题,但需要明确问题的根本原因。


问题解答

这个问题是11.50版本Informix的dbaccess工具的固有实现缺陷,核心原因如下:

  1. dbaccess本身的输出逻辑设计问题:当stdout是终端设备时,dbaccess默认会先输出少量控制字符或者空白换行做终端初始化,之后unload指令写入/dev/stdout的内容会追加在后面输出到终端,你看到的正常结果实际上是控制字符被终端自动忽略了,所以没显示出来。
  2. 当stdout是普通文件(即重定向场景)时,dbaccess的初始化输出和unload写入/dev/stdout的内容是两个独立的写入操作,两个操作共用同一个文件偏移指针:dbaccess先写入了一个换行符,偏移走到第1位,之后unload往/dev/stdout写数据时,会覆盖从偏移1开始的位置,所以首字符H被后续的换行覆盖了,就出现了你看到的结果。
  3. 当stdout是管道(比如传给hexdump、gzip、tee的时候),管道是流式设备没有偏移指针,两个写入的内容会按顺序拼接,所以gzip压缩后内容完整,传给hexdump也能看到完整的字符+额外换行。
  4. 你直接unload到普通文件时,数据是直接写入目标文件,和dbaccess自身的stdout输出完全分开,所以不会有冲突。

这个问题在后续的Informix 12.10及以上版本中已经被修复,对于11.50版本你现在用的tee/cat中转、或者直接unload到临时文件再读取的方案都是稳定可行的。


内容的提问来源于stack exchange,提问作者INS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 04:06:05