Як отримати пару значень ключа з команди ps


10

Я намагаюся витягти назву програми з такої psкоманди:

ps -af -u sas |grep "java"| grep -v "grep"

і він виробляє наступне:

sas 24431     1  0 Oct10 ?        00:51:08 /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs

Я спробував використовувати, egrepале, здається, не працює:

ps -af -u sas|grep "java"| grep -v "grep"| egrep -o "-Dapp.name"

Як я можу отримати лише -Dapp.nameзначення "myApp"?


якщо grepвізерунок починається з -, потрібно поставити його після -eопції. В іншому випадку це буде розглядатися як варіант. Але це буде відповідати лише слову -Dapp.name, а не частині після нього.
Barmar

по черзі:grep -o -- -Dapp.name
strugee

ви можете використовувати grep [j]avaдля уникнення команди grep -v "grep"(перевірена на bash)
HVNSweeting

Відповіді:



8

Ви не показуєте повідомлення про помилку, яке ви отримуєте, але це, ймовірно,

grep: метод невідомих пристроїв

Це тому, що, як і всі або принаймні більшість інших програм командного рядка, grepпередбачається, що все, що починається з а, -є варіантом і намагається проаналізувати його як таке. У цьому випадку -Dвикористовується для вказівки grepщодо того, як поводитися з файлом пристрою (див. man grepПодробиці). Одним із способів подолати це є використання, --яке говорить grepпро те, що все, що випливає, - це не прапор опції.

Поєднавши це з можливістю PCRE GNU grep, ви можете:

ps -af -u sas | grep -v grep | grep -Po -- '*-\KDapp.name=[^\s]+'

Регулярний вираз шукає a -і відкидає його ( \K), потім рядок, Dapp.name=за яким слідує якомога більше символів, що не містять пробілів. Вихід:

Dapp.name=myApp

Якщо ви хочете, щоб myAppчастина була збережена у змінній, я б шукав її самостійно:

ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+'

Щоб призначити його змінній:

$ app="$(ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+')"
$ echo $app
myApp

Однак ви ніколи не повинні отримувати grepрезультати psдля подібних речей, ось для чого pgrep:

app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"


3

Кожен раз, коли ви використовуєте ps … | grep …та потребуєте виключення grep з результатів, ви робите це неправильно.

Нульовим правилом аналізу результатів psє використання більш надійних інструментів, таких як, pgrepякщо вони є. Якщо у вас є pgrep, тоді pgrep -f javaперераховані всі процеси, що виконують команду java. Опція -lдодає командний рядок для кожного процесу.

Для вилучення аргументу -Dapp.nameможна скористатися sed. Збіжіть весь рядок, домовтеся, щоб скласти цікаву частину в групі, і роздрукуйте цю групу.

pgrep -lf java | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'

Перше правило розбору результатів ps- використовувати опцію -oдля вибору потрібних полів. Тут вас цікавлять лише аргументи команд, тому друкуйте лише це.

ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'

3

Складніше, ніж інші відповіді, але це використовується getoptдля обробки розбору для вас. Ще одна альтернатива.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. ваша команда: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' "видавлює" кілька просторів у єдиний простір для підготовки cut
  3. cut -d' ' -f8- розбиває лінію на пробіли і захоплює всі поля після 8 включно, результат є /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs
  4. getopts -aql 'Dapp.name:' $(...)аналізує параметри команд і виводить лише довге ім'я, яке відповідає тому, Dapp.nameхто має значення (позначається символом :), результат є--Dapp.name 'myApp' --
  5. cut -d"'" -f2 захоплює речі в єдиних цитатах
  6. Результат: myApp

0

Я б використав pgrepзамість psцього:

$ pgrep -fa java | grep -op "(<=-Dapp.name=)\w+"

Це поверне всі процеси, які відповідають, javaа потім відфільтрує ті, показуючи лише ті, що містять -Dapp.name=. Останній біт \w+покаже ім'я програми, припускаючи, що вона не містить пробілів.

ПРИМІТКА . -PПеремикач grepпередбачає можливість задавати речі за допомогою PCRE - Perl Compatible Regular Express . Не всі версії grepпідтримують його, але більшість з них є в комплекті з більш сучасними версіями Linux.

Якщо ви хочете вивести весь ключ / значення, то змініть такі речі:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.