Intereting Posts
Может ли awk использовать идентификаторы полей также для строк оболочки (переменных)? Режим zsh vi: просмотр последних команд, начиная с apt-get не находит phpldapadmin в Debian 9 (Stretch) Почему для настройки статического IP-адреса нужны «сетевые», «сетевые», «шлюзовые» и «DNS-серверы имен»? Изменение направления появления нового клиента в Awesome Window Manager Postfix не может отправлять электронную почту на популярные сайты электронной почты gmail Внутренняя ошибка синтаксического анализа: Недопустимый конверт Кому: адрес (недопустимое доменное имя): root @ Обоснование для создания текстового сегмента пользовательского пространства начинается с 0x8048000 Повторная настройка RAID автоматически? Arch Linux: Почему люди не делают «сделать установку» в PKGBUILD? Заменить очень длинную строку в файлах рекурсивно Сепаратор между списком команд и} Какую роль играет krb5.conf при подключении Linux-машины к AD через Samba / winbind? Решение целочисленного выражения ожидается Увеличение объема памяти ядра

Команда Grep с использованием содержимого heredoc

Я создаю скрипт для обновления удаленного компьютера, и я хочу знать, использует ли какой-либо пользователь компьютер до обновления. У меня есть список пользователей, и я создал heredoc со всеми из них. Команда, которую я пытаюсь сделать, выглядит примерно так:

ps -ef | grep -f | cat <<- END user1 user2 user3 END 

Что не работает. Что я могу сделать, чтобы фильтровать команду ps на основе моего списка пользователей с помощью heredoc?

Короткий ответ: ps -u user1,user2,user3


Ваша команда grep является неполной, поскольку для параметра -f требуется аргумент. Ваша команда cat получает свой вход от этого документа, поэтому, даже если вы исправили команду grep , ее выход будет отброшен.

Если вы ищете жестко запрограммированного пользователя, вы должны использовать

 ps -ef | grep alice 

(за исключением того, что это не очень хороший способ сделать это, как я объясню позже). Ввод в grep – это выход ps -ef . Вы можете передать несколько шаблонов поиска, передав несколько вариантов -e :

 ps -ef | grep -e alice -e bob 

Это печатает строки, содержащие alice или bob . Чтобы получить список входов из файла, вы можете использовать параметр -f , но для этого требуется имя файла.

 cat <<EOF >users.txt alice bob END ps -ef | grep -f users.txt 

Стандартный текст уже сделан для текста, который вы фильтруете, поэтому вы не можете повторно использовать его для шаблона поиска. Желание нескольких входов является общей проблемой, поэтому некоторые оболочки (ksh, bash, zsh) предлагают решение: замена процесса (что и было предложено don_crissti в комментарии ):

 ps -ef | grep -f <(cat <<END alice bob END ) 

Этот подход полезен, если список пользователей генерируется сложной командой, но с жестко запрограммированным списком он излишне сложный: grep -e alice -e bob выполняет ту же работу.


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

 ps -u alice,bob 

Если вы используете встроенную систему с версией ps , которая не поддерживает -u , посмотрите, поддерживает ли она -o USER , и используйте grep -x для соответствия всей строке.

 busybox ps -o user | grep -x -e alice -e bob 

В общем, я бы порекомендовал ответ Жилем .

Если вам нужен ваш скрипт для совместимости с POSIX, и ваш ps не поддерживает -u , это может сработать:

 ps -ef | grep -e \ "^smtpd ^dbus ^ntp" 

Т.е. вывести вывод ps -ef через grep -e pattern_list . Паттерн-образец поставляется как многострочная строка, каждый шаблон начинается с ^ чтобы привязать его к началу строки.