【问题标题】:"${line//END}" != "$line" - what does it do"${line//END}" != "$line" - 它有什么作用
【发布时间】:2020-10-19 19:07:57
【问题描述】:

所以我有一个包含 PEM 证书(其中许多)的文件的 API 调用结果,如下所示:

-----BEGIN CERTIFICATE-----
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBB
-----END CERTIFICATE-----


-----BEGIN CERTIFICATE-----
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAssssssssssssssssssssssssssssssssssssssssssssss
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdddddd
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAssss
-----END CERTIFICATE-----

在@user2856925 的帮助下回答这里 (https://serverfault.com/a/718751),我开始运行我的脚本,该脚本应该获取每个证书的到期日期。

while read line
do
    if [ "${line//END}" != "$line" ]; then
        txt="$txt$line\n"
        printf -- "$txt" | openssl x509 -enddate -noout  | cut -d "=" -f 2
        txt=""
    else
        txt="$txt$line\n"
    fi
done < /path/to/bundle/file

现在虽然这东西做了我想要的,但理解它是完美的,所以我可以在其他脚本中使用它。

那么让我们来回答问题吧。 "${line//END}" 是做什么的? // 在字符串上是什么,它正在检查 END 字是否包含在变量 line 中??!

我运行 bash -x 并看到变量 txt 被添加到下一行,直到找到 END CERTIFICATE 然后运行 ​​printf 行。所以在txt="$txt$line\n"这行之后,它又回到了那个时候?? 这将解释 txt="" 行清空变量以便下一个证书出现。

但是为什么我们需要else txt="$txt$line\n"??

该脚本还会忽略证书之间的所有空格 2 个或更多或根本没有空格,或者如果证书格式正确,它就可以正常工作,这很好,我没有抱怨,但它是怎么做的?

【问题讨论】:

标签: string bash while-loop parameter-expansion


【解决方案1】:

做一些基本的测试。

$: line='-----END CERTIFICATE-----'
$: echo $line
-----END CERTIFICATE-----
$: echo "${line//END}"
----- CERTIFICATE-----

从上面使用oguz ismail的优秀link -

"${line//END}" 是一个字符串替换,取 $line 的值并用 string 替换 pattern

诚然,手册页可能有点迟钝。基本上,结构是在左/开花括号内,就在要解析的变量的名称之后,你放一个斜线告诉解析器这是一个模式匹配/替换。由于第一个字段是要匹配/替换的模式,而空模式通常没有意义,所以如果下一个字符也是未转义的斜杠,那么它会使扫描全局(它通常只适用于第一次命中)。

这意味着END 是搜索模式。没有给出替换模式,因此没有使用任何替换模式 - 它被替换为空。

[ "${line//END}" != "$line" ] 则表示“尝试删除任何出现的 END,然后查看是否有任何变化。”它有效,但就个人而言,我不喜欢这种结构。您可以只使用搜索--

if [[ "$line" =~ END ]] # check for END

但我喜欢case 声明。

while read line
do case "$line" in
   *END*) txt="$txt$line\n"
          printf -- "$txt" | openssl x509 -enddate -noout  | cut -d "=" -f 2
          txt=""
   ;;
   *) txt="$txt$line\n"
   ;;
   esac
done < /path/to/bundle/file

将保留其他调整,而不是您要求的。 :)

【讨论】:

  • 我在您的代码中添加了一些消息,以便更好地理解它,并且使用案例语句肯定会更清楚。直到 END 行是 find.thanks Paul! while read line do case "$line" in *END*) echo "line at END ${line}" &gt;&gt; /tmp/1 txt="$txt$line\n" echo "txt at END ${txt}" &gt;&gt; /tmp/1 printf -- "$txt" | openssl x509 -enddate -noout | cut -d "=" -f 2 txt="" ;; *) echo "line at catch ${line}" &gt;&gt; /tmp/1 txt="$txt$line\n" echo "txt at catch ${txt}" &gt;&gt; /tmp/1 ;; esac done &lt; /tmp/tmpf
  • 关于文档,即使在阅读了很多次 ${parameter/pattern/string} 部分之后,世界上有人可能会想到以这种方式使用它……有趣的是它的存在方式用于解析那个巨大的文件并且不费心寻找 BEGIN 部​​分,而只是寻找 END 并检查由先前添加到该变量的所有行组成的证书。现在对我来说一个教育练习是使用数组而不是文件作为源,看看我是否可以让它工作。
  • 我会调整很多东西,但我是多动症/强迫症,哈哈。尽管如此,由于他们每次都在清空$txt,所以结果是一样的。
猜你喜欢
  • 2020-04-25
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多