Электронная почта bash regex

Я хочу в интерактивном режиме запросить у bash адрес электронной почты, пока он не получит действительный. Вот код

#!/bin/bash
email=""
email_status=[ "$email" =~ ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$ ]
while [ $email_status ]
do
    read -p "Enter admin email: " email
    echo
    if [[ "$email" =~ ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$ ]]
    then
        echo "Email address $email is valid."
    else
        echo "Email address $email is invalid."
    fi
done

Я не понимаю, почему не работает.

1 ответ

Решение

Основная проблема связана с той частью, где вы, кажется, устанавливаете условия для начального условия для while петля. Мы можем упростить весь цикл, просто выйдя из цикла при желаемом условии, например:

#!/bin/bash

while true
do
    read -p "Enter admin email: " email
    echo
    if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ ]]
    then
        echo "Email address $email is valid."
        break
    else
        echo "Email address $email is invalid."
    fi
done

который я также изменил, чтобы принимать символы нижнего регистра.

Так почему же начальная версия у вас не работает? Для начала, вы на самом деле не выполняете команду, которую хотите. Команда будет проанализирована с = назначение происходит первым, как будто вы назначаете локальную переменную оболочки для выполнения оставшейся команды. Так что в этом случае вы назначаете [ в email_statusзатем пытается выполнить "$email" =~ ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$ ] что не настоящая команда.

Даже если бы это было так, ваше назначение все равно не сработало бы, потому что то, чего вы на самом деле хотели бы (кроме использования [[ так что вы можете использовать синтаксис регулярных выражений), чтобы сделать этот тест, а затем сохранить код выхода в exit_status лайк:

[[ "$email" =~ ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$ ]]
email_status=$?

и затем убедитесь, что вы обновляете email_status в вашем цикле, чего не сделала ваша первоначальная версия.

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