【问题标题】:Capturing special characters from stdin to a shell variable将特殊字符从标准输入捕获到 shell 变量
【发布时间】:2020-08-03 00:12:03
【问题描述】:

我有一个程序打印包含空字节 \0 和特殊字符(如 \x1f 和换行符)的内容。例如:

someprogram

#!/bin/bash
printf "ALICE\0BOB\x1fCHARLIE\n"

给定这样一个程序,我想以这样一种方式读取它的输出,即所有这些特殊字符都被捕获在一个 shell 变量 output 中。所以,如果我运行:

echo $output

因为我没有提供 -e,所以我希望输出为:

ALICE\0BOB\x1fCHARLIE\n

如何做到这一点?

我的第一次尝试是:

output=$(someprogram)

但是我得到了这个没有特殊字符的回显输出:

./myscript.sh: line 2: warning: command substitution: ignored null byte in input
ALICEBOBCHARLIE

我也尝试使用read,如下:

output=""
while read -r
do
    output="$output$REPLY"
done < <(someprogram)

然后我摆脱了警告,但输出仍然缺少所有特殊字符:

ALICEBOBCHARLIE

那么如何捕获someprogram 的输出,以便在结果字符串中包含所有特殊字符?

编辑:请注意,在 bash 中可以有这样的字符串:

$ x="ALICE\0BOB\x1fCHARLIE\n"
$ echo $x
ALICE\0BOB\x1fCHARLIE\n

所以这应该不是问题。

EDIT2:既然我得到了一个可接受的答案并且我对事情的理解更好一点,我将重新提出这个问题。所以,我只需要能够将someprogram 的输出存储在某个shell 变量中,这样我就可以将它打印到stdout,而无需对任何特殊字符进行任何更改,就好像someprogram 只是直接通过管道传输到stdout。

【问题讨论】:

  • "\0" 只是两个字符,它 不是 一个零字节。我猜你想要:$'ALICE\x00BOB\x1fCHARLIE\n'

标签: bash special-characters stdout stdin


【解决方案1】:

您不能在 bash 变量中存储零字节。不可能。

通常的解决方案是将字节流转换为十六进制。然后在每次你想用它做某事时将它转换回来。

$ x=$(printf "ALICE\0BOB\x1fCHARLIE\n" | xxd -p)
$ echo "$x"
414c49434500424f421f434841524c49450a
$ <<<"$x" xxd -p -r | hexdump -C
00000000  41 4c 49 43 45 00 42 4f  42 1f 43 48 41 52 4c 49  |ALICE.BOB.CHARLI|
00000010  45 0a                                             |E.|
00000012

您也可以为此编写自己的序列化和反序列化函数。

我的另一个想法是例如通过使用零字节作为分隔符将数据读入数组(因为任何其他字节都是有效的)。然而,这将有区分尾随零字节的问题:

 $ readarray -d '' arr < <(printf "ALICE\0BOB\x1fCHARLIE\n")
 $ printf "%s\0" "${arr[@]}" | hexdump -C
 00000000  41 4c 49 43 45 00 42 4f  42 1f 43 48 41 52 4c 49   |ALICE.BOB.CHARLI|
 00000010  45 0a 00                                          |E..|
 #               ^^ additional zero byte if input doesn't contain a trailing zero byte
 00000013

【讨论】:

  • 谢谢! xxd 是一个完美的建议!为了我能够重新打印输出的目的,这就足够了:x=$(someprogram | xxd)echo $x | xxd -r
  • 我的问题肯定没有完美地表述,因为我上述评论中的启发式解决方案并不能完全回答原始问题。但是,如果没有一些避免真正问题的琐碎捷径,要制定一个具有我需要的属性的最小问题有点困难。无论如何,xxd 非常完美,非常感谢!!
猜你喜欢
  • 2019-04-10
  • 2011-03-05
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-04
相关资源
最近更新 更多