Ansible中如何通过调用Java类跨角色动态设置变量并赋值字典?
问题根源与解决办法
首先得明确一个关键:vars/main.yml是用来存放变量定义的,Ansible不会执行这个文件里的tasks块。你写的那两个shell任务根本没被运行,自然var1和var2就不存在,访问字典的时候肯定会提示变量未定义。
正确的实现步骤
1. 把执行Java命令的任务移到任务文件里
所有任务都应该放在tasks/main.yml(或者你的playbook任务块里),这是Ansible执行任务的正确位置。
2. 注册变量后定义结果字典
你可以用set_fact模块在任务执行后直接定义字典,或者在vars文件里引用已注册的变量(但要确保任务先执行)。
示例1:直接在任务中定义字典(推荐)
修改tasks/main.yml如下:
--- # 执行第一个Java命令,注册结果到var1 - name: 执行Java命令1 shell: "java -cp /path/to/your/class com.your.package.YourClass arg1" register: var1 # 执行第二个Java命令,注册结果到var2 - name: 执行Java命令2 shell: "java -cp /path/to/your/class com.your.package.YourClass arg2" register: var2 # 用set_fact定义字典,把注册的变量值存进去 - name: 构建结果字典 set_fact: my_dictionary: # 如果需要命令的标准输出,用stdout;要整个结果对象就直接写{{ var1 }} key1: "{{ var1.stdout }}" key2: "{{ var2.stdout }}"
示例2:在vars文件中定义字典(需确保任务先执行)
如果想把字典定义放在vars/main.yml,可以这么写:
--- my_dictionary: key1: "{{ var1.stdout }}" key2: "{{ var2.stdout }}"
但必须保证tasks/main.yml里的shell任务先于任何使用这个字典的任务执行,否则还是会因为变量未定义报错。
额外注意事项
- 如果你的Java命令需要特定的环境变量(比如
JAVA_HOME),可以在shell任务中添加environment参数指定:- name: 执行Java命令1 shell: "java -cp /path/to/your/class com.your.package.YourClass arg1" environment: JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64 register: var1 - 如果你需要的不是命令的输出,而是退出码,可以用
var1.rc;错误输出用var1.stderr。 - 注意shell命令的引号:如果命令里有空格或特殊字符,要确保用正确的引号包裹。
内容的提问来源于stack exchange,提问作者user3086551
相关产品推荐
相关产品推荐

