在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的兼容性。
要做到这一点在“谍影重重兼容”的方式,唯一的方法是使用外部工具。
除了在C书面方式之一,你可以使用xxd
和expr
(举例):
$ 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
被用于其转换回二进制能力。
需要注意的是厕所将失败,许多UNICODE字符(多字节字符):
$ printf "Voilà" | wc -c
6
$ printf "★" | wc -c
3
这将打印字节,而不是字符数。
一个变量的长度${#var}
也将无法在旧的炮弹。
当然,要得到这个在Bourne运行shell必须使用`…`
而不是$(…)
在bash
,在${parameter%word}
的形式壳牌参数扩展 ,可以使用:
$ output="$(printf "x\n\n"; echo X)"; echo -n "${output%X}" | wc -c 3
这是替代也被指定POSIX.1-2008 。