shell - 这个带有 printf -- "$(cat | sed...)" 的管道是如何工作的?
问题描述
第一个片段中发生了printf --
什么?如何printf
解析这样的命令以及最终的调用堆栈是什么样的?
$ printf '%x' 65537 | \
printf -- \
"$(cat | sed -E -e 's/^(.(.{2})*)$/0\1/' -e 's/(.{2})/\\x\1/g')" \
| openssl base64 -e
AQAB
$ printf '%x' 65537 | \
cat | sed -E -e 's/^(.(.{2})*)$/0\1/' -e 's/(.{2})/\\x\1/g' \
| openssl base64 -e
XHgwMVx4MDBceDAxCg==
解决方案
我认为您可能误读了您要询问的脚本。
在第一个示例中,printf
命令很简单:
printf '%x' 65537
这会将数字打印65537
为十六进制值 ( 10001
)。然后,该脚本使用 shell 管道符号 ( |
) 将该命令的输出传递printf
给第二个printf
命令:
printf -- "$(cat | sed -E -e 's/^(.(.{2})*)$/0\1/' -e 's/(.{2})/\\x\1/g')"
在此命令中,--
简单的意思是“在此之后没有 cli 选项”,用于确保之后--
看起来像选项的任何内容都不会被视为选项。该命令的其余部分是一个 shell$(...)
表达式,它将被包含在括号内的命令的输出替换:
cat | sed -E -e 's/^(.(.{2})*)$/0\1/' -e 's/(.{2})/\\x\1/g')
它从对 cat 的无用使用开始,它只是将标准输入(...这是上一个printf
命令的输出...)传递给 stdoutput。以下sed
命令包含两个表达式。第一个...
s/^(.(.{2})*)$/0\1/
...匹配任何包含奇数位数的行并在前面加上 a 0
,确保每一行都有偶数位数。第二个表达...
s/(.{2})/\\x\1/g
将每两个字符 ( nn
)替换为\xnn
,这是一个printf
格式代码,要求printf
打印具有给定 ASCII 值的字符。
然后将第二个命令的输出通过printf
管道传输到openssl base64 -e
中,它会根据stdout
接收到的任何内容生成 base64 编码stdin
。
所以当你运行时:
printf '%x' 65537 | \
printf -- \
"$(cat | sed -E -e 's/^(.(.{2})*)$/0\1/' -e 's/(.{2})/\\x\1/g')" \
| openssl base64 -e
这变成:
echo 10001 | printf -- '\x01\x00\x01' | openssl base64 -e
哪个输出:
AQAB
推荐阅读
- flutter - 使用 void 回调颤动的小部件通信
- c++ - 如何在我的 C++ 代码中使用 rapidjson 库?
- java - 在集成测试期间不要创建spring bean
- android - 在根项目“android”中找不到任务“assembleFIRDebugEnabledDebug”
- r - R中数据框中所有列的ECDF图
- sql-server - 使数据库表暂时只读(并且不引发错误)
- c# - 如何使用.Net Core 从网络接口接收所有 IPV6 数据包?
- python - Django ORM 使用字典数组排除记录
- mysql - 如何在 React 页面上显示存储在 MySQL 中的图像
- elasticsearch - 使用 logstash 在弹性搜索中将两个索引合并为第三个索引