如何使用ansible获取Linux命令`/usr/java/jdk-1.8/bin/java -version`的输出?

huangapple go评论89阅读模式
英文:

How do I get the output of a linux command /usr/java/jdk-1.8/bin/java -version using ansible?

问题

我正在尝试编写一个脚本,以获取安装在特定位置的Java版本。

当我使用下面的任务并提供完整路径时,返回的输出为空。当我将shell命令设置为java -version而不带路径时,它可以正常工作。

英文:

I am trying to write a script to fetch the java version which is installed in a specific location.

When I use the below task with the full path, the returned output is empty. When I give the shell command as java -version without the path, it works fine.

- name: Fetch Java version from location
  shell: /usr/java/jdk-1.8/bin/java -version 2>&1 | awk -F '"' '/version/ {print $2}'
  register: java_version_from_path
      
- name: Display the java version from the java location
  debug:
    msg: "{{ java_version_from_path.stdout }}"

答案1

得分: 2

您的代码按照原样对我有效,但在测试时,我输入错误的路径,出现了与您相同的行为。

因为您在管道中使用了一个 shell 任务,如果管道中的第一个命令失败,错误实际上被抑制了。考虑一下这个例子:

$ false | echo hello
hello
$ echo $?
0

第一个命令失败了,但没有办法知道。这正是我在本地运行Playbook时看到的行为,也可能是您问题的原因。

如果您将完整的命令行复制并粘贴到您的Shell中运行,它是否有效?如果只复制并粘贴 ../java -version 部分呢?

对于这种类型的任务,通常在Ansible中进行文本解析比使用 awk 更简单,类似这样:

- hosts: localhost
  gather_facts: false
  tasks:
  - name: 从位置获取Java版本
    command: /usr/java/jdk-17.0.2/bin/java -version
    register: java_version_from_path

  - name: 显示从Java位置获取的Java版本
    debug:
      msg: >-
        {{
          (
            java_version_from_path.stderr_lines |
            select('search', 'version') |
            first
          ).split('"')[1]
        }}

在我的系统上,这会产生:

TASK [从位置获取Java版本] *****************************************************************
changed: [localhost]

TASK [显示从Java位置获取的Java版本] **************************************************
ok: [localhost] => {
    "msg": "17.0.2"
}

通过在Ansible中执行文本解析,我们可以使用 command 任务,而不是 shell,并且如果java命令中有shell管道错误,将会传播到Playbook,我们会看到失败的信息:

TASK [从位置获取Java版本] *****************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "cmd": "/usr/java/jdk-1.8/bin/java -version", "msg": "[Errno 2] No such file or directory: b'/usr/java/jdk-1.8/bin/java'", "rc": 2, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
英文:

Your code works for me as written, but while testing it I mis-typed the path and got the same behavior as you.

Because you're using a shell task with a pipe, if the first command in the pipe fails the error is effectively suppressed. Consider this:

$ false | echo hello
hello
$ echo $?
0

The first command fails, but there's no way to tell. That's exactly the behavior I was seeing running the playbook locally, and it may be the cause of your problem.

If you copy and paste the full command line into your shell and run it, does it work? What if you just copy and paste the ../java -version part?


For this sort of task it's often simpler to do the text parsing in ansible rather than using awk; something like this:

- hosts: localhost
  gather_facts: false
  tasks:
  - name: Fetch Java version from location
    command: /usr/java/jdk-17.0.2/bin/java -version
    register: java_version_from_path

  - name: Display the java version from the java location
    debug:
      msg: >-
        {{
          (
            java_version_from_path.stderr_lines |
            select('search', 'version') |
            first
          ).split('"')[1]
        }}

On my system, this produces:

TASK [Fetch Java version from location] *****************************************************************
changed: [localhost]

TASK [Display the java version from the java location] **************************************************
ok: [localhost] => {
    "msg": "17.0.2"
}

By performing the text parsing in Ansible, we can use a command task, rather than shell, and without that shell pipeline errors in the java command will propagate to the playbook and we'll see the failure:

TASK [Fetch Java version from location] *****************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "cmd": "/usr/java/jdk-1.8/bin/java -version", "msg": "[Errno 2] No such file or directory: b'/usr/java/jdk-1.8/bin/java'", "rc": 2, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

huangapple
  • 本文由 发表于 2023年6月1日 19:17:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定