bash-4.1$ ps -ef|grep component_events.xml
gdxx1122 1190 1181 0 Mar25 ? 00:00:00 /xx1122/fmw/product/111/ohs_111/ohs/bin/odl_rotatelogs -l -h:/xx1122/admin/xx1122_vmabcd123/config/OHS/ohs1/component_events.xml_ohs1
/xx1122/admin/xx1122_vmabcd123/auditlogs/OHS/ohs1/audit-pid1181-%Y%m%d%H%M%S.log 1M 4M
gdxx1122 19885 19205 0 08:05 pts/1 00:00:00 grep component_events.xml
当我在脚本中运行上述命令时,可以提取“/xx1122/admin/xx1122_vmabcd123/config/OHS/ohs1”并分配给变量。上述输出可能因服务器而异,因此它必须是动态的。起始字符串 xx1122 必须动态传递
答案1
使用sed
POSIXly:
var=$(
ps -Ao args= | sed -n 's|.* -h:\(.*\)/component_events\.xml.*|\1|p'
)
/component_events.xml
实际上,这会返回最后一次出现和 之前最后一次出现之间的命令行部分-h:
。
所以如果命令行是:
... -h:x/component_events.xml -g:y/component_events.xml
你会得到x/components_events.xml -g:y
而不是x
.
您可以将其更改为sed -n 's|.* -h:\([^ ]*\)/component_events\.xml.*|\1|p'
以避免这种情况,但这样就不再适用于包含空格字符的目录名称。
在最近的 GNU/Linux 系统上,您还可以执行以下操作:
LC_ALL=C grep -zhPo '^-h:\K.*(?=/component_events\.xml)' /proc/*/cmdline |
tr '\0' '\n'
这适用于任何目录名称。
答案2
用于pgrep
查找 pid 和/proc/$PID/cmdline
:
var=$(
pgrep -f "component_events.xml" | \
xargs -I{} sh -c "head -z -n1 /proc/{}/cmdline | tr '\0' '\n'" | \
xargs -n1 dirname
)
当命令路径有参数并且找到多个 PID 时,这也适用。
解释:
搜索 PID:
pgrep -f "component_events.xml"
对于每个找到的 PID,获取完整命令 ( /proc/PID/cmdline
),但仅打印不带参数的命令 ( head -z -n1
)。
xargs -I{} sh -c "head -z -n1 /proc/{}/cmdline
然后\0
用换行符 ( \n
) 替换尾随:
tr '\0' '\n'"
仅输出目录名:
xargs -n1 dirname