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

Redirecting dbaccess output loses a character

在通过 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
~ #

正确的输出是“H300|1|”但是当我重定向时,我得到了一些奇怪的东西。我怀疑的是 dbacess 可执行文件向 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 hacks 或 gzip -c 来完成我的工作,但如果可能的话,我只是想要一个解释。

我的解决方案是像这样使用 grep(我会立即解释 || true 原因。

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

我做了一个 grep 以仅包含一些数据的行(只要“|”用作分隔符。

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

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

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