Проверить, соответствуют ли строки, соответствующие одному шаблону, также и другому

Я пытаюсь проверить все файлы с определенным расширением в текущей папке, чтобы увидеть, имеют ли те строки, которые содержат пары key=value, где ключ username, password или key, значение в форме ENC(...).

Если какое-либо username, password или key не связано со значением ENC(...), мне нужно обнаружить это и выдать ошибку.

В настоящее время я написал код, который ищет ENC(...), но это все, что он делает — он не ищет username, password или key.


Текущий код

#!/bin/bash
pattern='username password key'
find='ENC('   
FILE=test.properties  #need to search for *.properties on that folder 

if test -f "$FILE"; then
    echo "$FILE exists."
#need to check on the line that has a word in pattern if has the value of $find
# for example on the *.properties on line starting with username if it has the value of $find
    while read -r line
    do
        case $line in 
            *${find}*) 
                echo $line " encrypted" 
                ;;
        esac
    done < $FILE
else 
    echo "$FILE does not exist."    
fi

Прецедент

Следующее при запуске создает каталог, в котором скрипт должен выдавать вывод, подобный приведенному ниже:

#!/bin/sh
testdir = "$(mktemp -d "testdir.XXXXXX")" || exit
cd "$testdir" || exit

cat >a-good.properties <<EOF
# comments do not have any effect, neither do other keys
otherkey=also_ignored
# but other keys _can_ have encrypted values, it just doesn't matter
yet_another_key_but_encrypted=ENC(fffggghhh)

username=ENC(aaabbbccc)
password=ENC(bbbcccddd)
key=ENC(dddeeefff)
EOF

# a log with no key, value or password doesn't matter
cat >b-irrelevant.properties <<EOF
other_key=other_value
EOF

cat >c-bad.properties <<EOF
# this log has unencrypted data, we should fail when it exists
username=someone
password=ThisIsASecretDontTellAnyone
key=ThisIsAnotherSecret
EOF

echo "Test-suite files created in directory $testdir" >&2

Желаемый результат

a-good.properties exists.
username=ENC(aaabbbccc) is encrypted
password=ENC(bbbcccddd) is encrypted
key=ENC(dddeeefff) is encrypted
b-irrelevant.properties exists.
c-bad.properties exists.
ERROR: username should be encrypted but is not.
ERROR: password should be encrypted but is not.
ERROR: key should be encrypted but is not.

... и статус выхода должен быть ошибкой.

для одного файла проверит, существует ли значение, но не на основе шаблона

John Kon 23.03.2022 03:08

К вашему сведению, echo $line " encrypted" цитирует именно то, что неправильный. echo "$line" encrypted было бы лучше, или echo "$line encrypted" было бы еще лучше. printf '%s encrypted\n' "$line" будет даже лучше, чем оба, по причинам, описанным в Почему printf лучше эха?.

Charles Duffy 23.03.2022 03:09

... прямо сейчас, если ваша строка содержит ENC( * ), ваша echo напечатает список файлов в вашем текущем каталоге вместо *. Рассмотрите возможность запуска вашего кода через shellcheck.net, чтобы обнаружить этот класс проблем.

Charles Duffy 23.03.2022 03:10

Что касается вопроса, то он говорит, что вы пытаетесь сделать, он показывает ваш код, но не показывает, как этот код дает сбой. Убедитесь, что вы на самом деле задаю вопрос. «Почему этот код делает X вместо Y?» это пример вопроса, который должен быть добавлен редактировать в сам вопрос, а не добавлен в качестве комментария.

Charles Duffy 23.03.2022 03:10

Кроме того, из-за exit 1 вы выходите, когда находите строку Любые без ENC( в ней. Если вы хотите проверить только первую строку, зачем использовать цикл while read, созданный для чтения нескольких строк?

Charles Duffy 23.03.2022 03:13

Имейте в виду, что вы можете запустить read -r line <"$FILE" без каких-либо while, если все, что вы хотите сделать, это прочитать самую первую строку.

Charles Duffy 23.03.2022 03:14

(Кроме того, sh или bash? Если вы действительно нацелены на bash, вам не нужно case, потому что вы можете использовать [[ $line = *"$find"* ]], и вы должны удалить тег sh; тогда как, если вы нацеливаетесь на sh, вы должны удалить тег баш-тег).

Charles Duffy 23.03.2022 03:17

Вы показываете нам результат, который у вас есть (хотя было бы лучше в виде текста, а не снимка экрана), но, пожалуйста, также явно показывайте точный образец вывода, который вы хотеть.

Charles Duffy 23.03.2022 03:35

@CharlesDuffy это результат, который мне нужен ... мне нужно найти строки, которые начинаются с примера слова шаблона, если есть строка, начинающаяся с «пароля», если она имеет значение «ENC («» на данный момент она показывает только все строки со значением "ENC("

John Kon 23.03.2022 03:39

"например, если есть строка, начинающаяся с пароля, если она имеет значение ENC(" -- тогда какая? Это предложение описывает условие, но не описывает желаемый ответ, связанный с этим условием.

Charles Duffy 23.03.2022 03:48

Одна вещь, которая добавляет путаницы, заключается в том, что вы показываете нам пример выход, но не показываете пример ввода, который соответствует этому выводу.

Charles Duffy 23.03.2022 03:50

... если входной файл содержит ровно password=ENC(cEjemHosjc/hjA8sad), то разве выходной файл уже не такой, каким вы хотите его видеть?

Charles Duffy 23.03.2022 03:50

Если вы хотите сопоставить именно password=ENC(*), измените *${find}*) на password=ENC(*) (я не вижу веских причин использовать здесь переменную find)

Charles Duffy 23.03.2022 03:52

(кстати, меня нет на вечер; любое будущее участие будет около 8 часов).

Charles Duffy 23.03.2022 03:53

@CharlesDuffy спасибо за ваше время. входной файл будет состоять из всех файлов *.properties внутри папки scripts, например. если «шаблон» не зашифрован, это означает, что значение не будет начинаться с ENC (даст выход 1

John Kon 23.03.2022 07:29

Ах! Это, наконец, хорошее объяснение того, чего вы пытаетесь достичь; Спасибо тебе за это.

Charles Duffy 23.03.2022 12:12

Кстати, в будущем вы должны искать дубликаты для как можно большего количества частей проблемы и сужать вопрос, чтобы задавать только конкретные проблемы, для которых у нас нет дубликатов. Например, у нас уже есть дубликат для Перебрать все файлы с определенным расширением для циклической части.

Charles Duffy 23.03.2022 12:48

Более важно то, что вывод примера полезен только для людей когда он связан с примером ввода. Нам не нужно угадывать, каков ваш ожидаемый формат ввода - я собираюсь немного отредактировать вопрос, чтобы продемонстрировать, как выглядит вопрос с минимальный воспроизводимый пример, включая добавление моих собственных предположений в пример ввода; пожалуйста, подтвердите их.

Charles Duffy 23.03.2022 12:51

Готово. Имеет ли это смысл с точки зрения того, что потребуется, чтобы написать лучший вопрос в следующий раз?

Charles Duffy 23.03.2022 13:05

@CharlesDuffy ваше редактирование было точным. Спасибо за ваше время. Я проверил дубликаты, но не нашел нужных мне частей. Я буду иметь это в виду на будущее.

John Kon 23.03.2022 13:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
20
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Переход от выражений в стиле glob (используемых с case) к регулярным выражениям с синтаксисом ERE облегчит вашу задачу.

Учитывая описание проблемы, которую вы пытаетесь решить из комментариев, реализация этого в собственном bash (в отличие от использования таких инструментов, как grep) может выглядеть так:

#!/usr/bin/env bash
case $BASH_VERSION in '') echo "ERROR: must be run with bash" >&2; exit 1;; esac

faults_found=0
encryption_required_re='^[[:space:]]*(username|password|key)=(.*)$'
encryption_present_re='ENC[(][^)]+[)]'

for file in *.properties; do
    if [[ -f $file ]]; then
        echo "$file exists" >&2
    else
        continue # no properties files found so the glob didn't expand
    fi
    while IFS= read -r line; do
        # ignore lines that do not match encryption_required_re
        [[ $line =~ $encryption_required_re ]] || continue
        key=${BASH_REMATCH[1]}; value=${BASH_REMATCH[2]}
        # ignore lines where value matches encryption_present_re
        [[ $value =~ $encryption_present_re ]] && {
          printf '%s\n' "$key=$value encrypted" >&2
          continue
        }
        # flag so the script fails on exit, and print an alert to stderr
        (( ++faults_found ))
        printf '%s\n' "ERROR: $file: $key should be encrypted but is not" >&2
    done <"$file"
done

# exit with status 1 if faults_found is nonzero
exit $(( faults_found ? 1 : 0 ))

См. реплику, выполняющую этот код (измененный только для простоты тестирования) по адресу https://replit.com/@CharlesDuffy2/NavyThirdVerification#example.bash.


В противном случае быстрый и грязный подход с grep может выглядеть так:

#!/bin/sh
if grep -Ee '^(username|password|key)=' *.properties \
   | grep -Ev '=ENC[(].*[)]'; then
  echo "ERROR: Found unencrypted secrets" >&2
  exit 1
else
  echo "No unencrypted secrets found" >&2
  exit 0
fi

... обратите внимание, что этот записывает эти незашифрованные секреты на ваш терминал, что может быть нежелательным поведением.

Другие вопросы по теме