我正在编写一个脚本,并将其用作变量。
RESULT1=`ps -ef | grep -w "PHANTOM PHA-WRM-EXPIRE"`.
发生的情况是ps
列出两个 PID。
[xhobando@noitu TNOITU]$ ps -ef | grep -w "/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE"
phantomxg 7250 1 0 12:15 ? 00:00:01 /usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE
phantomxg 17071 1 0 Oct04 ? 00:05:27 /usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE
我在这里想要实现的是,该grep
选项仅查找第一个 PID,而不查找两个 PID。
让我知道这是否有意义。
答案1
使用带有 PCRE 支持的GNU grep
(rhel 上的实现):
ps -Ao pid= -o args= |
grep -Pom1 '^\s*\K\d+(?= \Q/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE\E)'
在哪里
-P
切换到P
类似 erl 的正则表达式(对于\s
、\K
、\d
、(?=...)
、\Q
、\E
所有类似 perl 的扩展)。-o
告诉grep
只输出匹配的部分-m1
告诉grep
只输出第一个匹配行的匹配项。
(所有 3 个标志恰好都是 GNU 扩展,但 GNUgrep
恰好是grep
在 RHEL 上找到的实现)。
我们不使用ps -f
which 打印一些我们不关心的字段,而是只选择我们需要的字段(pid
和args
,=
后缀是为了删除标题),这样我们就可以更轻松地在命令行上进行匹配。
这里,正则表达式查找^
由 0 个或更多 ( *
) 个空白字符 ( ) 组成的前导 ( \s
) 序列,之后我们标记匹配的开始 ( ),后跟由 1 个或更多 ( ) 个数字 ( )\K
组成的序列,前提是它们是后面(向前看运算符,不是匹配的一部分)是一个空格和我们想要的参数(用...引用,以便更容易替换为可能包含正则表达式运算符的其他参数列表)。+
\d
(?=...)
\Q
\E
或者只是使用pgrep
:
pgrep -f '^/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE' | head -n 1
将返回第一个进程的 pid,该进程的 arg 列表(与空格字符连接)以 开头/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE
。
ps
请注意,进程在or的输出中默认按 pid 进行数字排序pgrep
,并且 pid 数字在达到最大值时会换行,因此您将获得的数字或多或少是随机的。
您可能想要添加一些--sort start_time
或--sort -start_time
,例如ps
按开始时间排序(或添加-o
/-n
最老的/最新并pgrep
删除| head -n 1
) 如果您想获取最早/最晚启动的进程,而不是保证它是最晚启动的进程被处决udt
第一个/最后一个进程可以并且经常在其生命周期中运行多个命令。
如果,正如您对问题的评论所暗示的那样,您想根据当前工作目录选择进程,您可以使用以下zsh
方法:
pids=(
/proc/<1->(e[$'[[ $REPLY/cwd -ef /tdata/PHANTOM &&
$(<$REPLY/cmdline) = /usr/ud/bin/udt\0PHANTOM\0PHA-WRM-EXPIRE\0* ]]']:t)
)
在这里,查找以/tdata/PHANTOM
、/usr/ud/bin/udt
和作为其前 3 个参数PHANTOM
的进程PHA-WRM-EXPIRE
。
但请注意,除非您的进程具有超级用户权限,否则您只能找到自己进程的工作目录。