Bash exec$SHELL从SSH执行,赢得';不要在剧本中执行

Bash exec$SHELL从SSH执行,赢得';不要在剧本中执行,bash,vagrant,ansible,ansible-playbook,Bash,Vagrant,Ansible,Ansible Playbook,我正在尝试在来宾VM上提供Ruby+Rails。以下是我的剧本中的内容。yml: --- - hosts: all sudo: true tasks: - apt: update_cache=yes - apt: name={{ item }} state=present with_items: - build-essential - git-core - zlib1g-dev - libssl-

我正在尝试在来宾VM上提供Ruby+Rails。以下是我的
剧本中的内容。yml

---
- hosts: all
  sudo: true
  tasks:
    - apt: update_cache=yes
    - apt: name={{ item }} state=present
      with_items:
        - build-essential
        - git-core
        - zlib1g-dev
        - libssl-dev
        - libreadline-dev
        - libmysqlclient-dev
        - libyaml-dev
        - libxml2-dev
        - libxslt1-dev
        - libcurl4-openssl-dev
        - python-software-properties
        - libffi-dev
        - curl
    - command: git clone git://github.com/sstephenson/rbenv.git .rbenv
    - shell: echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
    - shell: echo 'eval "$(rbenv init -)"' >> ~/.bashrc
    - shell: exec $SHELL
    - command: git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
    - shell: echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
    - shell: exec $SHELL
    - command: git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash
    - command: rbenv install 2.2.3
    - command: rbenv global 2.2.3
    - shell: echo 'gem{{":"}} --no-ri --no-rdoc' >> ~/.gemrc
    - command: gem install bundler
    - command: add-apt-repository -y ppa:chris-lea/node.js
    - apt: update_cache=yes
    - apt: name=nodejs state=present
    - command: gem install rails -v 4.2.2
    - command: rbenv rehash
设置时,Ansible始终挂起在task
-shell:exec$shell
上,并且不返回。但是当我SSH到机器中并运行
exec$SHELL
时,它会执行并返回。当我在剧本中使用
-command:exec$SHELL
时,Ansible会打印以下错误:

failed: [default] => {"cmd": "exec /bin/bash", "failed": true, "rc": 2}
msg: [Errno 2] No such file or directory
我可以确认
/bin/bash
是否存在


发生什么事了?我已经为此挣扎了半天了。请告知。

首先,我不建议你做这样的事情:

- shell: echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
- shell: echo 'eval "$(rbenv init -)"' >> ~/.bashrc
如果您碰巧在主机上多次运行此playbook,那么您将在.bashrc文件中得到这些命令的多个实例,这是您不希望看到的。你应该考虑你的.BasHC文件,或者至少使用一些类似的东西来确保这些条目只被添加一次。 就这项任务而言:

- shell: exec $SHELL
这是你绝对不应该做的事情。这当然不会产生您可能期望的结果,并且表明您没有完全理解任务(尤其是shell任务)是如何工作的
exec
用指定的命令替换现有shell。如果您在尝试此操作时没有遇到错误,那么您实际上要做的就是替换Ansible启动的shell以运行此命令。理论上会发生的情况是,shell Ansible启动时会被另一个shell替换,Ansible会因为等待shell终止而挂起,但您执行的shell没有执行任何操作,因此它永远不会终止

一旦执行此任务,您的playbook将无法继续运行。您可能需要ctrl+c来终止ansible playbook,或者您需要登录到远程主机并杀死ansible正在等待的shell,此时playbook将由于任务失败而终止

切换到
-command:shell$shell
也会失败,因为
exec
是一个内置的shell命令,但如下所示:

给定的命令。。。将不会通过外壳进行处理

由于
命令
模块直接执行命令,而不是通过shell执行命令,因此无法识别shell内置的
exec
。这就是为什么您会收到上面指出的错误消息

也许您应该提供一个详细的解释,说明您正在尝试做什么,以及为什么您认为需要以这种方式调用
exec$SHELL

你也应该考虑改变这样的任务:

 - command: gem install bundler

改为使用。通常,您希望尽可能使用内置的Ansible模块,并且仅使用shell/command等作为最后手段。内置模块提供了更好的错误处理、参数验证等功能。

Wow。谢谢你提供这些信息,伙计。正如您所知,我对Ansible和bash一无所知,我只想快速设置Rails开发环境并完成所有这些操作。我试着将上面的说明改编成我的剧本,但显然我做得不对。现在前进的道路是明确的。谢谢@窦:我和你有同样的错误。我还为ruby安装了虚拟机。你能和我分享一下你的剧本吗?