获取shell命令的确切输出 [英] Get exact output of a shell command
问题描述
bash
手册针对命令替换:
Bash通过执行命令并将命令替换替换为命令的标准输出来执行扩展,并删除所有尾随的换行符.
Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.
演示-3个字符,第一个换行符:
Demonstration - 3 characters, newlines first:
$ output="$(printf "\n\nx")"; echo -n "$output" | wc -c
3
这里的换行符不是末尾,也不会被删除,因此计数为3.
Here the newlines are not at the end, and do not get removed, so the count is 3.
演示-3个字符,最后一行换行:
Demonstration - 3 characters, newlines last:
$ output="$(printf "x\n\n")"; echo -n "$output" | wc -c
1
此处换行符从末尾删除,因此计数为1.
Here the newlines are removed from the end, so the count is 1.
什么是将命令的二进制干净输出转换为变量的稳健解决方法?
What is a robust work-around to get the binary-clean output of a command into a variable?
Bourne外壳兼容性的奖励点.
Bonus points for Bourne shell compatibility.
推荐答案
以与伯恩兼容"的方式做到这一点的唯一方法是使用外部实用程序.
The only way to do it in a "Bourne compatible" way is to use external utilities.
除了用c写一个,还可以使用 xxd
和 expr
(例如):
Beside writting one in c, you can use xxd
and expr
(for example):
$ 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
是因为它具有转换回二进制文件的功能.
The command xxd
is being used for its ability to convert back to binary.
请注意,wc将失败,并带有许多UNICODE字符(多字节字符):
Note that wc will fail with many UNICODE characters (multibyte chars):
$ printf "Voilà" | wc -c
6
$ printf "★" | wc -c
3
它将打印字节数,而不是字符数.
It will print the count of bytes, not characters.
在较旧的shell中,变量 $ {#var}
的长度也会失败.
The length of a variable ${#var}
will also fail in older shells.
当然,要使其在Bourne shell中运行,您必须使用`…`
而不是 $(...)
.
Of course, to get this to run in a Bourne shell you must use `…`
instead of $(…)
.
这篇关于获取shell命令的确切输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!