重定向 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[@]}
验证了它们。
除非有人在合理的时间内对此做出解释,否则我不会选择这个作为正确答案。
如前所述,我已经解决了问题并记录了所有内容。
在通过 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[@]}
验证了它们。
除非有人在合理的时间内对此做出解释,否则我不会选择这个作为正确答案。
如前所述,我已经解决了问题并记录了所有内容。