Sad*_*nny 12 script bash ansible
我无法从 Ansible 剧本“分离地”运行远程应用程序启动脚本。脚本将运行,但我无法让它获得/保持分离。我可能做错了什么,但什么?
这是我的复制器。
我在 Test.java 中的远程 Java 应用程序运行了 10 秒:
class Test {
public static void main(String[] args) {
for (int I = 1; I <= 10; i++) {
System.out.println("Hello world " + I);
try { Thread.sleep(1000);
} catch (Exception e) { System.out.println("Exception caught: " + e);
}
} } }
Run Code Online (Sandbox Code Playgroud)将其编译为 Test.class (javac Test.java),然后使用“java Test”运行该类按预期工作(给出 10 条输出消息,然后退出)。
我运行此应用程序的可执行 shell 脚本(如在 chmod 755 中)如下所示:
#!/bin/bash
java Test &
Run Code Online (Sandbox Code Playgroud)手动运行它也完全没问题:Java 应用程序在我的控制台中运行并生成相同的标准输出,但 shell 脚本已经退出,我重新控制了我的 bash 会话。
现在通过来自另一台服务器的 ansible playbook 运行它。我尝试以不同的方式使用“command”模块和“shell”模块,但无济于事......
---
- hosts: vagrant1
gather_facts: false
tasks:
- debug: msg="Running test app through Ansible shell module..."
- name: Start application
shell: "/tmp/test.sh"
args:
chdir: "/tmp"
executable: "/bin/bash"
- debug: msg="Running test app through Ansible command module..."
- name: Start application
command: "nohup /tmp/test.sh &"
args:
chdir: "/tmp"
Run Code Online (Sandbox Code Playgroud)所有这些都运行得很好,即 shell 脚本运行,Java 应用程序运行并执行其操作(即运行 10 秒,生成输出并退出)。但是 ansible-playbook 会一直运行,直到 Java 应用程序完成,然后返回 Java 应用程序生成的输出。为什么它不只是分离 shell 脚本并完成剧本?
ansible-playbook 输出是:
monsterkill@monsterkill-ub-dt:~/playbooks$ ansible-playbook testrun.yaml -v
PLAY [vagrant1] ***************************************************************
TASK: [debug msg="Running test app through Ansible shell module..."] **********
ok: [vagrant1] => {
"msg": "Running test app through Ansible shell module..."
}
TASK: [Start application] *****************************************************
changed: [vagrant1] => {"changed": true, "cmd": " /tmp/test.sh ", "delta": "0:00:10.052927", "end": "2015-01-29 00:14:43.327418", "rc": 0, "start": "2015-01-29 00:14:33.274491", "stderr": "", "stdout": "Hello world 1\nHello world 2\nHello world 3\nHello world 4\nHello world 5\nHello world 6\nHello world 7\nHello world 8\nHello world 9\nHello world 10"}
TASK: [debug msg="Running test app through Ansible command module..."] ********
ok: [vagrant1] => {
"msg": "Running test app through Ansible command module..."
}
TASK: [Start application] *****************************************************
changed: [vagrant1] => {"changed": true, "cmd": ["nohup", "/tmp/test.sh", "&"], "delta": "0:00:10.045643", "end": "2015-01-29 00:14:53.557164", "rc": 0, "start": "2015-01-29 00:14:43.511521", "stderr": "nohup: ignoring input", "stdout": "Hello world 1\nHello world 2\nHello world 3\nHello world 4\nHello world 5\nHello world 6\nHello world 7\nHello world 8\nHello world 9\nHello world 10"}
PLAY RECAP ********************************************************************
vagrant1 : ok=4 changed=2 unreachable=0 failed=0
Run Code Online (Sandbox Code Playgroud)
use*_*062 19
只需使用一个异步操作以poll: 0:
- command: yourscript.sh
async: 45
poll: 0
Run Code Online (Sandbox Code Playgroud)
需要这些选项来防止ansible使用os.killpg杀死该任务的子进程。
然后在 yourscript.sh 中:
java Test &
disown
Run Code Online (Sandbox Code Playgroud)
disown 从作业表中删除进程,因此 SIGHUP 不会发送给它。nohup 做同样的事情,但不是必需的。
编辑:请注意,并非所有外壳都提供 disown(例如破折号)
谷歌服务器现在肯定在冒烟,但我找到了一个解决方案。当我意识到 Ansible 通过单独的 ssh 调用执行其所有远程命令时,我通过从 ansible 服务器手动执行此操作进行了测试,发现它与 ssh 功能有关。
显然,答案是让我调用的脚本执行双重背景技巧,结合 nohup 使其忽略挂断信号 (SIGHUP) 并结合断开 stdout 和 stderr 流。因此,远程启动脚本不再执行:
java Test &
Run Code Online (Sandbox Code Playgroud)
...但现在这样做:
( ( nohup java Test 1>/dev/null 2>&1 ) & )
Run Code Online (Sandbox Code Playgroud)
这做我想要的。ansible-playbook 现在启动远程脚本,该脚本反过来启动 java 应用程序,然后双重背景和 nohups 并断开输出流。
这个stackoverflow线程帮助了我。
使用 start-stop-daemon 将脚本作为守护程序运行在这里似乎是一个更优雅的解决方案。http://manpages.ubuntu.com/manpages/raring/man8/start-stop-daemon.8.html
- name: Start application
shell: "start-stop-daemon --start --quiet --pidfile /var/run/test --exec /tmp/test.sh"
args:
executable: "/bin/bash"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50244 次 |
| 最近记录: |