如何用纯Bash将多行证书Base64块替换为文本格式输出?
纯Bash方案处理OpenSSL证书转换
一、核心实现函数
下面是纯Bash编写的处理函数,能自动捕获s_client输出中的每个证书块,转换为文本格式输出:
process_certs() { local in_cert=0 local tmp_file=$(mktemp) while IFS= read -r line; do # 进入证书块 if [[ "$line" == "-----BEGIN CERTIFICATE-----" ]]; then in_cert=1 echo "$line" > "$tmp_file" continue fi # 退出证书块,执行转换 if [[ "$line" == "-----END CERTIFICATE-----" ]]; then in_cert=0 echo "$line" >> "$tmp_file" openssl x509 -in "$tmp_file" -text -noout echo -e "\n=== 证书分割线 ===" rm -f "$tmp_file" continue fi # 处于证书块内则写入临时文件,否则直接输出原内容 if [[ $in_cert -eq 1 ]]; then echo "$line" >> "$tmp_file" else echo "$line" fi done }
使用方式
直接通过管道将s_client的输出传入函数即可:
openssl s_client -showcerts -connect example.net:443 | process_certs
二、OpenSSL原生支持情况
OpenSSL没有原生参数能直接将s_client输出的多证书块自动转换为文本格式。如果仅处理单个证书,可以用如下命令,但不适用于证书链场景:
openssl s_client -connect example.net:443 | openssl x509 -text -noout
这条命令只能提取并转换第一个证书,后续的证书链会被忽略,因此处理完整证书链还是需要自定义逻辑。
三、sed/awk/perl的局限性
- sed:默认单行处理,多行匹配依赖复杂的
N/P/D组合逻辑,面对行数不固定的证书块,容易出现漏匹配或逻辑混乱 - awk:虽支持自定义记录分隔符,但用证书起止标记作为分隔符时,难以同时保留非证书部分的输出,处理逻辑不够直观
- perl:多行正则匹配能力强,但对于不熟悉Perl语法的用户,代码维护成本高于纯Bash实现
内容的提问来源于stack exchange,提问作者Tomáš Hůbelbauer
相关产品推荐
相关产品推荐

