如何获取 Linux 中已运行进程的命名选项的值?

如何获取 Linux 中已运行进程的命名选项的值?

我运行以下命令。

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

我收到以下输出。

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

我可以使用什么命令来获取打印参数的值(例如-mor-t-p)?我想实现以下目标。

ps -e -o args | grep destiny | grep UNIX | <someCommand> -p这应该打印1501

ps -e -o args | grep destiny | grep UNIX | <someCommand> -m这应该打印UNIX

ps -e -o args | grep destiny | grep UNIX | <someCommand> -t这应该打印TCP

请注意,-p-m或可能会切换列,因此无法-t使用打印和按数字选择列。awk

更多事实使解析变得更容易(我知道我可能只是缺乏工具知识)。

  • 如果选项不存在,将返回空字符串
  • 在这种特殊情况下,将被解析的选项将始终有一个参数/值

答案1

这通常是不可能的,因为只有命令本身知道如何解析它自己的参数。以你的例子为例:

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

-p可以是一个不带参数的选项(如布尔值:它启用或禁用某些行为),在这种情况下1501将是一个位置参数(如文件名或其他东西)。或者-p可能是一个带有参数的选项,其参数是1501。没有办法知道它是什么!

参数向量只是零个或多个字符串的列表。这些字符串没有附加任何含义,指示哪些是选项,哪些是这些选项的参数,哪些是非选项参数。

即使您示例中的选项也-r无法进行一般性解析。鉴于-r紧随其后的是另一个以 开头的字符串-,这极有可能是-r一个不带参数的选项(就像启用或禁用某些行为的布尔值),但实际上这并不是 100% 确定。-r可以是一个带有参数的选项并且-m将是它的参数。或者该命令可能根本不遵循正常的 UNIX 约定,并且-r根本不是一个选项!

答案2

怎么样使用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 withoptions
  • s 是搜索。
  • .* 匹配任何/所有字符,直到我们到达“-t”。
  • \s 匹配任何空格。
  • ( 开始捕获。
  • [A-Z0-9]* 匹配任意大写字母和任意长度的任意数字。
  • ) 结束捕获。
  • .* 匹配该行中的其余字符(如果有)。
  • \1 用捕获替换所有内容。

答案3

您可以使用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将会重置开始。

请注意,这只会处理简单的情况(请参阅塞拉达的答案)。

另一种方式,使用后视:

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

答案4

这是一个Python单行代码。 (我使用 python 是因为 perl 和 awk 没有简单的方法来获取列表中值的位置。)

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

只要您尝试提取的参数不包含空格,它就可以工作。

相关内容