2

Я пытаюсь получить список запущенных сервисов. Я побежал

service --status-all

Это вернет что-то вроде

 [ + ]  acpid
 [ ? ]  alsa-utils
 [ + ]  apache2
 [ + ]  atd
 [ + ]  avahi-daemon
 [ ? ]  binfmt-support
 [ + ]  bluetooth
 [ - ]  bootlogd
 [ - ]  bootlogs

Я пытаюсь grep, и он пытается работать со специальными символами.

sudo service --status-all | grep '+'

Есть ли что-нибудь, что я могу сделать, чтобы заставить его работать правильно.

1 ответ1

6

Я пытаюсь grep, и он пытается работать со специальными символами.

При включенных базовых регулярных выражениях (BRE) (по умолчанию в отсутствие ключей -E , -F или -P) grep интерпретирует символ плюс как литерал + .

Проблема в том, что в STDOUT отправляются только строки, начинающиеся с [ + ] или [ - ] , а строки, начинающиеся с [ ? ] отправить в STDERR. Только STDOUT получает доступ к grep; STDERR печатается прямо на терминале.

Чтобы получить ожидаемый вывод, выполните следующую команду:

service --status-all 2>&1 | grep '+'

2>&1 отправляет STDERR в STDOUT, поэтому grep может его отфильтровать.

Поскольку вы печатаете только строки, начинающиеся с  [ + ]   , вы также можете отфильтровать эту часть. Для этого вы можете использовать ключ -o для печати только совпадающих выходных данных, ключ -P для включения регулярных выражений, совместимых с Perl (PCRE), и утверждение для проверки ((?<=...)):

service --status-all 2>&1 | grep -Po '(?<= \[\ \+ \]  ).*'

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

Тот же результат может быть достигнут с помощью BRE, не обращая внимания и не зная точного количества пробелов, если вы используете sed:

service --status-all 2>&1 | grep '+' | sed 's/.*] *//'

Здесь BRE .*] * (Все, вплоть до правой скобки, за которым следует любое количество пробелов), заменяется пустой строкой.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .