无法使用Ansible来源.bashrc

pld*_*rov 73 ansible

我可以ssh到远程主机并做source /home/username/.bashrc- 一切正常.但是,如果我这样做:

- name: source bashrc
  sudo: no
  action: command source /home/username/.bashrc
Run Code Online (Sandbox Code Playgroud)

我明白了:

failed: [hostname] => {"cmd": ["source", "/home/username/.bashrc"], "failed": true, "rc": 2}
msg: [Errno 2] No such file or directory
Run Code Online (Sandbox Code Playgroud)

我不知道我做错了什么......

Ste*_*ley 77

您有两个选项可以使用ansible源代码.一个是"shell:"命令和/ bin/sh(ansible默认值)."来源"被称为"." 在/ bin/sh.所以你的命令是:

- name: source bashrc
  sudo: no   
  shell: . /home/username/.bashrc && [the actual command you want run]
Run Code Online (Sandbox Code Playgroud)

请注意,您必须在采购之后运行命令.bashrc b/c每个ssh会话都是不同的 - 每个ansible命令都在单独的ssh事务中运行.

你的第二个选择是强制Ansible shell使用bash然后你可以使用"source"命令:

- name: source bashrc
  sudo: no   
  shell: source /home/username/.bashrc && [the actual command you want run]
  args:
     executable: /bin/bash
Run Code Online (Sandbox Code Playgroud)

最后,我会注意到,如果您使用的是Ubuntu或类似设备,您可能想要实际获取"/ etc/profile",这样可以更完整地模拟本地登录.

  • 我在.bashrc中定义了一些bash函数,并在获取.bashrc之后.我该如何执行/调用这些功能?我正在尝试`shell :. 〜/ .bashrc && nvm install {{node_version}}`它就是说'找不到'nvm命令'.我怎么解决这个问题? (4认同)
  • 另请注意,此问题已作为Ansible核心中的错误/功能请求提交(并由我评论).但Ansible关闭它并说"写一个插件." 呸.https://github.com/ansible/ansible/issues/4854 (3认同)
  • @RaviTezu:在我的案例中的问题是由于 .bashrc 中的以下几行: # 如果不是交互式运行,不要做任何事情 case $- in *i*) ;; *) 返回;; esac 这至少是 ubuntu-16.04 xenial64 上的一个问题,其中 .bashrc 不在非交互式 shell 上运行,这是通过 ssh 运行命令时的情况。要尝试一下,请在 ~/.bashrc 中设置一些 PATH 并运行(假设您已将端口 2222 设置为来宾操作系统上的 22): ssh -p 2222 ubuntu@127.0.0.1 'echo $PATH' 如果上述命令没有' t 显示您在 .bashrc 中设置的 PATH 然后修复 .bashrc (2认同)

Ric*_*ico 20

所以command只会运行可执行文件. source本身不是可执行文件.(这是一个内置的shell命令).您有什么理由想要source一个完整的环境变量吗?

还有其他方法可以在Ansible中包含环境变量.例如,environment指令:

- name: My Great Playbook
  hosts: all
  tasks:
    - name: Run my command
      sudo: no
      action: command <your-command>
      environment:
          HOME: /home/myhome
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用shellAnsible模块:

- name: source bashrc
  sudo: no
  action: shell source /home/username/.bashrc && <your-command>
Run Code Online (Sandbox Code Playgroud)

要么

- name: source bashrc
  sudo: no   
  shell: source /home/username/.bashrc && <your-command>
Run Code Online (Sandbox Code Playgroud)

在这些情况下,一旦运行Ansible步骤,shell实例/环境将终止.

  • 几乎不错,不幸的是 /bin/sh 没有 source 命令 only 。所以 `shell source /home/username/.bashrc` 变成了 `shell 。/home/用户名/.bashrc` (2认同)

Cle*_*pat 16

我知道这个答案来得太晚了但我已经看到足够的代码你可以使用sudo选项了-i :

- name: source bashrc
  shell: sudo -iu {{ansible_user_id}} [the actual command you want run]
Run Code Online (Sandbox Code Playgroud)

正如文档中所述

The -i (simulate initial login) option runs the shell specified by the password database entry of the target user as a login shell.  This means that login-specific
               resource files such as .profile or .login will be read by the shell.  If a command is specified, it is passed to the shell for execution via the shell's -c option.
               If no command is specified, an interactive shell is executed.  sudo attempts to change to that user's home directory before running the shell.  It also initializes
               the environment to a minimal set of variables, similar to what is present when a user logs in.  The Command environment section below documents in detail how the -i
               option affects the environment in which a command is run.
Run Code Online (Sandbox Code Playgroud)


Jur*_*lak 11

许多回复建议使用 source ~/.bashrc 但主要问题是 ansible shell 不是交互式的,并且 ~/.bashrc 实现默认忽略非交互式 shell(检查其开头)。

我发现在 ssh 交互式登录后以用户身份执行命令的最佳解决方案是:

- hosts: all
  tasks:
    - name: source user profile file
      #become: yes
      #become_user: my_user  # in case you want to become different user (make sure acl package is installed)
      shell: bash -ilc 'which python' # example command which prints
      register: which_python
    - debug:
      var: which_python
Run Code Online (Sandbox Code Playgroud)

bash:“-i”表示交互式 shell,因此 .bashrc 不会被忽略“-l”表示获取完整用户配置文件的登录 shell


小智 7

在尝试让 virtualenvwrapper 在 Ubuntu 服务器上工作时,我遇到了同样的问题。我像这样使用 Ansible:

- name: Make virtual environment
  shell: source /home/username/.bashrc && makevirtualenv virenvname
  args:
    executable: /bin/bash
Run Code Online (Sandbox Code Playgroud)

但源命令不起作用。

最终我发现 .bashrc 文件在文件顶部有几行,这些行在 Ansible 调用时阻止源代码工作:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac
Run Code Online (Sandbox Code Playgroud)

我在 .bashrc 中注释掉了这些行,之后一切都按预期工作。


Hea*_*ren 5

我已经使用ansible 2.4.1.0尝试了上述所有选项,直到另外两个选项才起作用,这里是重新生成案例的详细信息。

$ cat ~/.bash_aliases 
alias ta="echo 'this is test for ansible interactive shell'";
Run Code Online (Sandbox Code Playgroud)

这是ansible 测试

- name: Check the basic string operations
  hosts: 127.0.0.1 
  connection: local

  tasks:
  - name: Test Interactive Bash Failure
    shell: ta
    ignore_errors: True

  - name: Test Interactive Bash Using Source
    shell: source ~/.bash_aliases && ta
    args:
      executable: /bin/bash
    ignore_errors: yes

  - name: Test Interactive Bash Using .
    shell: . ~/.bash_aliases && ta
    ignore_errors: yes

  - name: Test Interactive Bash Using /bin/bash -ci
    shell: /bin/bash -ic 'ta'
    register: result
    ignore_errors: yes

  - debug: msg="{{ result }}"

  - name: Test Interactive Bash Using sudo -ui
    shell: sudo -ui hearen ta
    register: result
    ignore_errors: yes

  - name: Test Interactive Bash Using ssh -tt localhost /bin/bash -ci
    shell: ssh -tt localhost /bin/bash -ci 'ta'
    register: result
    ignore_errors: yes
Run Code Online (Sandbox Code Playgroud)

这是结果:

$ ansible-playbook testInteractiveBash.yml 
 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [Check the basic string operations] ************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************
ok: [127.0.0.1]

TASK [Test Interactive Bash Failure] ****************************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": "ta", "delta": "0:00:00.001341", "end": "2018-10-31 10:11:39.485897", "failed": true, "msg": "non-zero return code", "rc": 127, "start": "2018-10-31 10:11:39.484556", "stderr": "/bin/sh: 1: ta: not found", "stderr_lines": ["/bin/sh: 1: ta: not found"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Test Interactive Bash Using Source] ***********************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": "source ~/.bash_aliases && ta", "delta": "0:00:00.002769", "end": "2018-10-31 10:11:39.588352", "failed": true, "msg": "non-zero return code", "rc": 127, "start": "2018-10-31 10:11:39.585583", "stderr": "/bin/bash: ta: command not found", "stderr_lines": ["/bin/bash: ta: command not found"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Test Interactive Bash Using .] ****************************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": ". ~/.bash_aliases && ta", "delta": "0:00:00.001425", "end": "2018-10-31 10:11:39.682609", "failed": true, "msg": "non-zero return code", "rc": 127, "start": "2018-10-31 10:11:39.681184", "stderr": "/bin/sh: 1: ta: not found", "stderr_lines": ["/bin/sh: 1: ta: not found"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Test Interactive Bash Using /bin/bash -ci] ****************************************************************************************************************************************
changed: [127.0.0.1]

TASK [debug] ****************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "msg": {
        "changed": true, 
        "cmd": "/bin/bash -ic 'ta'", 
        "delta": "0:00:00.414534", 
        "end": "2018-10-31 10:11:40.189365", 
        "failed": false, 
        "rc": 0, 
        "start": "2018-10-31 10:11:39.774831", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "this is test for ansible interactive shell", 
        "stdout_lines": [
            "this is test for ansible interactive shell"
        ]
    }
}

TASK [Test Interactive Bash Using sudo -ui] *********************************************************************************************************************************************
 [WARNING]: Consider using 'become', 'become_method', and 'become_user' rather than running sudo

fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": "sudo -ui hearen ta", "delta": "0:00:00.007906", "end": "2018-10-31 10:11:40.306128", "failed": true, "msg": "non-zero return code", "rc": 1, "start": "2018-10-31 10:11:40.298222", "stderr": "sudo: unknown user: i\nsudo: unable to initialize policy plugin", "stderr_lines": ["sudo: unknown user: i", "sudo: unable to initialize policy plugin"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Test Interactive Bash Using ssh -tt localhost /bin/bash -ci] **********************************************************************************************************************
hearen@localhost's password: 
changed: [127.0.0.1]

PLAY RECAP ******************************************************************************************************************************************************************************
127.0.0.1                  : ok=8    changed=6    unreachable=0    failed=0  
Run Code Online (Sandbox Code Playgroud)

有两种可行的选择:

  • shell: /bin/bash -ic 'ta'
  • shell: ssh -tt localhost /bin/bash -ci 'ta'但是这个需要本地输入密码。