获取shell命令的确切输出

时间:2016-10-05 03:12:26

标签: bash shell

bash手册说明了command substitution

  

Bash通过执行命令并用命令的标准输出替换命令替换执行扩展,删除任何尾随换行符。

演示 - 首先是3个字符,换行符:

$ output="$(printf "\n\nx")"; echo -n "$output" | wc -c
3

此处换行符不在最后,并且不会被删除,因此计数为3。

演示 - 最后3个字符,换行符:

$ output="$(printf "x\n\n")"; echo -n "$output" | wc -c
1

此处新行将从末尾删除,因此计数为1.

TL; DR

什么是健壮解决方法,将命令的二进制清理输出变为变量?

Bourne shell兼容性的加分点。

2 个答案:

答案 0 :(得分:2)

在" Bourne兼容"中进行此操作的唯一方法方法是使用外部工具。

除了在c中写一个,你可以使用xxdexpr(例如):

$ output="$(printf "x\n\n"; printf "X")"         # get the output ending in "X".
$ printf '%s' "${output}" | xxd -p               # transform the string to hex.
780a0a58
$ hexstr="$(printf '%s' "${output}" | xxd -p)"   # capture the hex
$ expr "$hexstr" : '\(.*\)..'                    # remove the last two hex ("X").
780a0a
$ hexstr="$(expr "$hexstr" : '\(.*\)..')         # capture the shorter str.
$ printf "$hexstr" | xxd -p -r | wc -c           # convert back to binary.
3

缩短:

$ output="$(printf "x\n\n"; printf "X")"
$ hexstr="$(printf '%s' "${output}" | xxd -p )"
$ expr "$hexstr" : '\(.*\)..' | xxd -p -r | wc -c
3

命令xxd正被用于转换回二进制的能力。

请注意,wc会因许多UNICODE字符(多字节字符)而失败:

$ printf "Voilà" | wc -c
6

$ printf "★" | wc -c
3

它将打印字节数,而不是字符。

变量${#var}的长度在旧shell中也会失败。

当然,要让它在Bourne shell中运行,您必须使用`…`而不是$(…)

答案 1 :(得分:0)

bash中,可以使用${parameter%word}形式的Shell Parameter Expansion

$ output="$(printf "x\n\n"; echo X)"; echo -n "${output%X}" | wc -c
3

此替换也由POSIX.1-2008指定。