Итак, у меня есть результат вызова API к файлу, содержащему сертификаты PEM (многие из них), например:

-----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 в переменной строке ??!

Я запустил bash -x и увидел, что переменная txt добавляется в следующую строку, пока не будет найден КОНЕЦ СЕРТИФИКАТА, после чего будет запущена строка printf. Значит, после этой строки txt="$txt$line\n" она возвращается в то время ?? Это объясняет строку txt="", которая очищает переменную, поэтому идет следующий сертификат.

Но тогда зачем нам else txt="$txt$line\n" ??

Сценарий также игнорирует все эти пробелы 2 или более или вообще отсутствуют между сертификатами, или, если сертификат правильно отформатирован, он просто работает, и это здорово, я не жалуюсь, но как это сделать?

-1
trustbyte 29 Июн 2020 в 18:12

1 ответ

Лучший ответ

Сделайте небольшое базовое тестирование.

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

Используя превосходный oguz-ismail"> oguz ismail /manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion:%7E:text=%24%7Bparameter%2F&text=If%20pattern%20begins%20with%20%E2%80%98/%E2% 80% 99,% 20all% 20 соответствует% 20of% 20pattern% 20are% 20replaced% 20with% 20string. " rel = "nofollow noreferrer"> ссылка сверху -

"${line//END}" - это замена строки, принимающая значение $line и выполняющая замену pattern на string .

По общему признанию, справочные страницы могут быть немного тупыми. По сути, структура такова, что внутри левой / открытой фигурной формы, сразу после имени переменной, которую нужно проанализировать, вы помещаете косую черту, чтобы сообщить парсеру, что это сопоставление / замена шаблона. Поскольку первое поле - это шаблон для сопоставления / замены, а пустой шаблон обычно не имеет смысла, поэтому, если следующий символ также является неэкранированной косой чертой, тогда сканирование становится глобальным (обычно это применяется только к первому попаданию).

Это означает, что 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

Остальные настройки оставлю не такими, как вы просили. :)

0
Paul Hodges 29 Июн 2020 в 16:26