Как использовать grep, когда файл не содержит строку? Проверка существования пользователя в “passwd” или нет.

Вопрос или проблема

В моем сценарии bash я пытаюсь вывести строку, если определенная строка не существует в файле.

if grep -q "$user2" /etc/passwd; then
    echo "Пользователь существует!!"

Вот как я это написал, если хотел, чтобы строка существовала в файле. Но как я могу изменить это, чтобы он печатал “пользователь не существует”, если пользователь не найден в файле /etc/passwd?

grep вернет успех, если найдет хотя бы одно вхождение шаблона, и неудачу, если не найдет. Таким образом, вы можете добавить условие else, если хотите получить оба вывода “существует” и “не существует”, или просто отрицать условие if, чтобы получить только неудачи. Пример каждого:

if grep -q "$user2" /etc/passwd; then
    echo "Пользователь существует!!"
else
    echo "Пользователь не существует!!"
fi

if ! grep -q "$user2" /etc/passwd; then
    echo "Пользователь не существует!!"
fi

Вы можете использовать опцию grep “-L / –files-without-match”, чтобы проверить, содержит ли файл строку:

if [[ $(grep -L "$user2" /etc/passwd) ]]; then   
  echo "Пользователь не существует!!"; 
fi

Альтернатива – проверить статус выхода grep. Например:

grep -q "$user2" /etc/passwd
if [[ $? != 0 ]]; then
    echo "Пользователь не существует!!"

Если grep не находит совпадение, он завершится с кодом 1, поэтому $? будет 1. grep всегда возвращает 0, если успешно. Так что безопаснее использовать $? != 0 вместо $? == 1.

grep -q query_text ./file.txt && echo true || echo false

Я решаю это с помощью простого однострочного решения:

for f in *.txt; do grep "tasks:" $f || echo $f; done

Команда проверит все файлы в каталоге с расширением txt и либо запишет поисковую строку (т.е. “tasks:”), если она найдена, либо имя файла.

Чтобы выяснить, является ли имя пользователя в $user2 допустимым пользователем в этой системе, используйте getent passwd "$user2". Это либо даст вам запись базы данных паролей для пользователя, либо завершится с ненулевым кодом выхода, если пользователь не существует:

if ! getent passwd "$user2" >/dev/null
then
    printf 'Пользователь "%s" не существует\n' "$user2"
fi

Не используйте grep. Предположим, у вас есть два пользователя, mattias и smatteo, и вы хотите проверить, существует ли matt. Если вы используете grep 'matt' в файле passwd, вы обязательно увидите обоих пользователей и любого другого пользователя с подстрокой matt где-либо в их записи базы данных паролей. Ваш код тогда сделает вывод, что “пользователь matt существует”, даже если это не так.

Кроме того, если вы используете какую-либо службу каталогов, ваши пользователи могут не храниться вовсе в /etc/passwd. Тем не менее, команда getent должна работать.

Ответ или решение

Конечно! Давайте подробно рассмотрим, как использовать команду grep для проверки наличия пользователя в файле /etc/passwd, а также альтернативные подходы и лучшие практики для этой задачи.

Проверка существования пользователя в файле /etc/passwd с помощью grep

Команда grep позволяет искать строки, содержащие определённый текст, в файле. Для проверки, существует ли пользователь в файле /etc/passwd, можно использовать grep следующим образом:

if grep -q "$user2" /etc/passwd; then
    echo "Пользователь существует!!"
else
    echo "Пользователь не существует!!"
fi

В данном случае флаг -q указывает на то, что grep должен работать в тихом режиме, не выводя соответствующие строки, а лишь возвращая статус завершения. Если пользователь найден (статус 0), то выведется сообщение о том, что пользователь существует, в противном случае – о том, что он не существует.

Негативная проверка с использованием !

Можно изменить условие if, чтобы проверять, если grep не нашёл пользователя:

if ! grep -q "$user2" /etc/passwd; then
    echo "Пользователь не существует!!"
fi

Этот подход делает код более компактным, так как вы не используете оператор else.

Использование grep -L для поиска файлов без совпадений

Вы также можете воспользоваться опцией -L, которая позволяет выводить имена файлов, не содержащих матчей, но для вашего случая это не совсем подходящее решение, так как нам только нужно проверить один файл:

if grep -L "$user2" /etc/passwd; then
  echo "Пользователь не существует!!" 
fi

Проверка статуса выхода с помощью $?

Вы можете проверить код завершения grep с помощью переменной $?, которая содержит код выхода последней выполненной команды:

grep -q "$user2" /etc/passwd
if [[ $? -ne 0 ]]; then
    echo "Пользователь не существует!!"
fi

Однако, использование ! grep является более читаемым и предпочтительным подходом.

Лучший способ: Использование getent

Хотя grep подходит для этой задачи, рекомендуется использовать команду getent для более надежной проверки существования пользователя:

if ! getent passwd "$user2" >/dev/null; then
    printf 'Пользователь "%s" не существует\n' "$user2"
fi

Преимущества использования getent:

  1. Она учитывает не только локальных пользователей, но и пользователей из сетевых служб, таких как LDAP.
  2. Это позволяет избежать возможных ложных срабатываний, когда пользователь имеет схожее имя.

Заключение

Для проверки существования пользователя рекомендуется использовать getent, что делает ваш скрипт более универсальным. В случае необходимости работы только с локальным файлом /etc/passwd, методы с использованием grep также подходят. Однако важно помнить, что для предотвращения ложных срабатываний лучше использовать более сильные методы, такие как getent.

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

Оцените материал
Добавить комментарий

Капча загружается...