You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Ansible的ps命令结果中提取Tomcat参数并生成列表

问题描述

在Ansible中执行ps命令获取Tomcat进程信息,已将命令输出的stdout_lines存入dataresult变量,成功提取了运行Tomcat的用户列表,但无法提取catalina.home、catalina.base和logging.properties路径。希望存在多个Tomcat实例时,将这些参数分别存入对应列表,尝试的提取任务未成功,求解决。


现有相关任务与输出

1. 获取Tomcat进程的Shell任务

- name: Check running processes
  shell: ps aux | grep -i "[t]omcat"
  register: tomcat_process_cmd

2. 存储stdout_lines的任务

- name: tomcat process stdout
  set_fact: 
    dataresult: "{{ tomcat_process_cmd.stdout_lines}}"

3. 已实现的用户提取任务

- name: Create dictionary for tomusers
  set_fact:
    tom_users: "{{tom_users | default([]) + [ item.split()[0]] }}"
  loop: "{{ dataresult }}"

4. 尝试失败的参数提取任务

- name: Create dictionary for java.util.logging.config.file
  set_fact:
    log_propss: "{{ item.split()[8] | item.0.split('=') }}"
  loop: "{{ dataresult }}"
  when: tomcat_process_cmd.stdout | regex_search('logging.config.file')

命令输出示例

tomcat  1183735  0.2 33.3 14596700 2631076 ?    Sl   May10   8:54
/usr/bin/java
-Djava.util.logging.config.file=/opt/apache/tomcat/9.0.85/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Dcom.sun.jndi.ldap.connect.pool.protocol=plain ssl
-Dcom.sun.jndi.ldap.connect.pool.authentication=none simple DIGEST-MD5
-Djdk.tls.ephemeralDHKeySize=5248
-Djava.protocol.handler.pkgs=org.apache.catalina.webresources
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Xmx8192m
-Dignore.endorsed.dirs= -classpath
/opt/apache/tomcat/9.0.85/bin/bootstrap.jar:/opt/apache/tomcat/9.0.85/bin/tomcat-juli.jar
-Dcatalina.base=/opt/apache/tomcat/9.0.85
-Dcatalina.home=/opt/apache/tomcat/9.0.85
-Djava.io.tmpdir=/opt/apache/tomcat/9.0.85/temp
org.apache.catalina.startup.Bootstrap start

期望输出格式

users: [userA, userB]
catalinahome: [catalinahome1, catalinahome2]
catalinabase: [catalinabase1, catalinabase2]
loggingprops: [logpath1, logpath2]

解决方案

问题核心是stdout_lines按行拆分,而Tomcat启动参数分散在多行,无法按单行直接处理。以下是两种可行解决方法:

方法一:合并进程行后精准提取

先将同一Tomcat进程的多行输出合并为单条字符串,再针对每个进程提取对应参数,保证用户与参数严格对应:

- name: 合并同一进程的多行输出
  set_fact:
    tomcat_processes: "{{ tomcat_processes | default([]) + [current_process] }}"
  vars:
    current_process: >-
      {% if tomcat_processes is undefined %}
        {{ item }}
      {% else %}
        {{ tomcat_processes[-1] + ' ' + item }}
      {% endif %}
  loop: "{{ tomcat_process_cmd.stdout_lines }}"
  when: >-
    tomcat_processes is undefined 
    or not item matches '^\w+\s+\d+'

- name: 提取所有Tomcat实例的参数
  set_fact:
    tom_users: "{{ tom_users | default([]) + [item | regex_search('^([\\w-]+)\\s+', '\\1') | first] }}"
    catalinahome: "{{ catalinahome | default([]) + [item | regex_search('-Dcatalina\\.home=([^\\s]+)', '\\1') | first] }}"
    catalinabase: "{{ catalinabase | default([]) + [item | regex_search('-Dcatalina\\.base=([^\\s]+)', '\\1') | first] }}"
    loggingprops: "{{ loggingprops | default([]) + [item | regex_search('-Djava\\.util\\.logging\\.config\\.file=([^\\s]+)', '\\1') | first] }}"
  loop: "{{ tomcat_processes }}"

方法二:直接从完整stdout提取(简洁版)

若无需严格绑定用户与参数的对应关系,可直接从整个stdout中提取所有匹配的参数:

- name: 提取用户列表
  set_fact:
    tom_users: "{{ tomcat_process_cmd.stdout | regex_findall('^([\\w-]+)\\s+\\d+', '\\1') }}"

- name: 提取catalina.home列表
  set_fact:
    catalinahome: "{{ tomcat_process_cmd.stdout | regex_findall('-Dcatalina\\.home=([^\\s]+)', '\\1') }}"

- name: 提取catalina.base列表
  set_fact:
    catalinabase: "{{ tomcat_process_cmd.stdout | regex_findall('-Dcatalina\\.base=([^\\s]+)', '\\1') }}"

- name: 提取logging.properties路径列表
  set_fact:
    loggingprops: "{{ tomcat_process_cmd.stdout | regex_findall('-Djava\\.util\\.logging\\.config\\.file=([^\\s]+)', '\\1') }}"

说明

  • 正则表达式-Dcatalina\.home=([^\s]+)会匹配-Dcatalina.home=后直到空格的所有字符,即完整路径。
  • regex_findall直接返回所有匹配结果形成列表,无需循环拼接。

内容的提问来源于stack exchange,提问作者maddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:35:06