重定向dbaccess输出丢失一个字符



当通过dbaccess可执行文件使用informix数据库的转储时,我遇到了一个非常奇怪的问题。

以下是问题的表现:

~ # echo "unload to /dev/stdout [ select statement ]" |  dbaccess db 2>/dev/null
H300|1|
~ # 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
~ # 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
~ #

正确的输出是"0";H300|1|";但当我重定向时,我会得到一些奇怪的东西。我怀疑dbaccess可执行文件向stdout写入的内容会干扰同样写入同一文件(/dev/stdout(的转储。

卸载到与stdout不同的文件会产生以下输出:

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

注意:如果我使用gzip-c,那么输出的gzip文件包含有效的数据,没有丢失字符,就像输入一样。

数据库设置:

~ # 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
~ #

在具有相同行为的操作系统上运行:

test_shell:cat /etc/SUSE-brand
SLE
VERSION = 15
test_shell:uname -a
Linux test-linux 5.3.18-22-default #1 SMP Wed Jun 3 12:16:43 UTC 2020 (720aeba) x86_64 x86_64 x86_64 GNU/Linux
test_shell:

test_shell2:/home/# cat /etc/SuSE-release
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 4
test_shell2:/home/# uname -a
Linux test-linux 3.0.101-63-default #1 SMP Tue Jun 23 16:02:31 UTC 2015 (4b89d0c) x86_64 x86_64 x86_64 GNU/Linux
test_shell2:/home/# cat /etc/SuSE-brand
SLES
VERSION = 11
CO-BRANDS = SLE openSUSE
test_shell2:/home/#

因此,在SLES15SP2和SLES11SP4上都会发生这种情况。我可以简单地使用cat/tee技巧或gzip-c来完成我的工作,但如果可能的话,我只想得到一个解释。

在我的案例中,解决方案是这样使用grep(我将立即解释|| true的原因。

echo "unload to /dev/stdout delimiter '|' [ select statement ]" |  dbaccess db 2>/dev/null | (grep '|' || true)

我做了一个grep,只包含一些数据的行(只要"|"用作分隔符即可。

我使用|| true来确保管道中的命令没有一个失败,因为我在bash中使用${PIPESTATUS[@]}来验证它们。

除非其他人在合理的时间内对此做出解释,否则我不会选择这个答案作为正确答案。

如前所述,我已经解决了这个问题,并记录了所有内容。

最新更新