Как получить значение именованного параметра уже запущенного процесса в Linux?

Я запускаю следующую команду.

ps -e -o args | grep destiny | grep UNIX 

Я получаю следующий вывод.

 /path/to/destiny -r -m UNIX -t TCP -p 1501 

Какую команду я могу использовать, чтобы получить значение напечатанных аргументов (например, -m или -t или -p )? Я хотел бы добиться следующего.

ps -e -o args | grep destiny | grep UNIX | <someCommand> -p ps -e -o args | grep destiny | grep UNIX | <someCommand> -p это должно печатать 1501

ps -e -o args | grep destiny | grep UNIX | <someCommand> -m ps -e -o args | grep destiny | grep UNIX | <someCommand> -m это должно печатать UNIX

ps -e -o args | grep destiny | grep UNIX | <someCommand> -t ps -e -o args | grep destiny | grep UNIX | <someCommand> -t это должно печатать TCP

Обратите внимание, что -p , -m или -t могут переключаться между столбцами, поэтому печать с awk и выбор столбца по номеру не является опцией.

Еще несколько фактов, так что синтаксический анализ становится проще (я знаю, что возможно, мне просто не хватает знаний по инструментам).

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

4 Solutions collect form web for “Как получить значение именованного параметра уже запущенного процесса в Linux?”

Как насчет использования sed :

 ps -e -o args | grep -e 'destiny.*UNIX' | sed -e 's/.*-t\s\([A-Z0-9]*\).*/\1/' ps -e -o args | grep -e 'destiny.*UNIX' | sed -e 's/.*-p\s\([A-Z0-9]*\).*/\1/' ps -e -o args | grep -e 'destiny.*UNIX' | sed -e 's/.*-m\s\([A-Z0-9]*\).*/\1/' 

sed -e 's/.*-t\s\([A-Z0-9]*\).*/\1/'

  • s / search for / replace with / options
  • s – поиск.
  • . * соответствует любому / всем символам, пока мы не перейдем к «-t».
  • \ s соответствует любому пробелу.
  • (начинается захват.
  • [A-Z0-9] * соответствует любой заглавной букве и любому количеству любой длины.
  • ) завершает захват.
  • . * соответствует оставшейся части символов в строке (если они есть).
  • \ 1 заменяет все на захват.

Это невозможно вообще, потому что только сама команда знает, как разбирать свои собственные аргументы. Принимая ваш пример:

 /path/to/destiny -r -m UNIX -t TCP -p 1501 

-p может быть вариантом, который не принимает аргументов (например, boolean: он включает или отключает какое-либо поведение), и в этом случае 1501 будет позиционным аргументом (например, именем файла или чем-то еще). Или -p может быть опцией, которая принимает аргумент, и его аргумент равен 1501 . Невозможно узнать, что это такое!

Вектор аргумента – это всего лишь список из нуля или более строк. Нет смысла прикреплять к этим строкам, указывающим, какие из них являются опциями, какие из них являются аргументами для этих опций, а какие – аргументы без опционов.

Даже вариант -r в вашем примере не может быть в общем случае проанализирован для определенного. Учитывая, что -r сразу следует другой строкой, которая начинается с - , в подавляющем большинстве вероятность того, что -r является опцией, которая не принимает аргументов (например, логическое значение, которое включает или отключает какое-либо поведение), но на самом деле это не на 100%. -r может быть вариантом, который принимает аргумент, а -m – его аргументом. Или команда может вообще не следовать нормальным соглашениям UNIX, и -r не является вообще вариантом!

Вы можете использовать grep :

 ~$ echo "/path/to/destiny -r -m UNIX -t TCP -p 1501" | grep -oP -- '-t \K[^ ]+' TCP ~$ echo "/path/to/destiny -r -m UNIX -t TCP -p 1501" | grep -oP -- '-p \K[^ ]+' 1501 

(у вас может быть / нужно использовать такие вещи, как \s вместо одного пространства: grep -oP -- '-p\s\K[^\s]+' )

-o означает «распечатать только соответствие», \K сбросит начало.

Обратите внимание, что это будет обрабатывать только простые случаи (см. Ответ Celada для чего).

Другой способ, используя look-behind:

 grep -oP -- '(?<=-p )[^ ]+' 

Вот однострочный python. (Я использую python, потому что perl и awk не имеют простого способа получить позицию значения в списке.)

 ps -eo args | grep '/path/to/destiny' | python -c 'x=input().split(); print(x[ x.index("-p")+1 ])' 

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

  • Как удалить старые резервные копии на основе даты в имени файла?
  • как совместить слова и игнорировать пробелы
  • Извлечь подстроку с символом вместо позиции
  • Выполнить строку из сценария оболочки как набор команд оболочки
  • Asteriks в имени файла, поскольку wildcard не работает
  • Сравните пользователей с массивом с файлом / etc / shadow
  • проблемы, связанные с скриптом с $ # и циклом
  • Как добавить пользовательский скрипт в док-станцию ​​в элементарной ОС Freya
  • как я могу найти файлы на основе разных имен и удалять их все в одной строке
  • Тестирование открытого TCP-порта в сценарии bash
  • bash добавляет апострофы к расширенной переменной
  • Linux и Unix - лучшая ОС в мире.