【问题标题】:Ansible doesn't load ~/.profileAnsible 不加载 ~/.profile
【发布时间】:2016-06-29 13:15:00
【问题描述】:

我在问自己为什么 Ansible 在一台主机上执行 template 模块之前不获取 ~/.profile 文件?

远程主机~/.profile

export ENV_VAR=/usr/users/toto

单个 Ansible 任务:

- template: src=file1.template dest={{ ansible_env.ENV_VAR }}/file1

Ansible 失败:

fatal: [distant-host] => One or more undefined variables: 'dict object' has no attribute 'ENV_VAR'

【问题讨论】:

    标签: ansible


    【解决方案1】:

    Ansible 没有在交互式或登录 shell 中运行远程任务(命令、shell、...)。就像通过 'ssh user@host "which python"' 远程执行命令一样 源 ~/.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
    

    bash: '-i' 表示交互式 shell,所以 .bashrc 不会被忽略 '-l' 表示登录 shell,它获取完整的用户配置文件(/etc/profile 和 ~/.bash_profile,或 ~/.profile - 请参阅 bash 手册页了解更多详细信息)

    我的示例说明:我的 ~/.bashrc 从安装在该用户下的 anaconda 设置特定的 python。

    【讨论】:

    • 这对我有用(-c 从字符串中读取选项)
    • 它可以工作,但对 stderr 有一点抱怨:“bash: 无法设置终端进程组 (70071): Inappropriate ioctl for device\nbash: no job control in this shell”
    【解决方案2】:

    Ansible 没有在远程主机上的交互式 shell 中运行任务。 Michael DeHaan 前段时间回答了这个问题on github

    超级基本的描述是 ansible 并不是真正通过 shell 做事,它是传输模块并执行它传输的脚本,而不是使用登录 shell。

    Why does an SSH remote command get fewer environment variables then when run manually?

    它基本上不是一个连续的shell环境,也不是登录和输入命令之类的东西。

    您应该通过运行以下命令看到相同的结果(未定义的变量):

    ssh <host> echo $ENV_VAR
    

    【讨论】:

      【解决方案3】:

      在很多地方我都使用过以下结构:

      - name: Task Name
        shell: ". /path/to/profile;command"
      

      【讨论】:

      • 这确实对我有用,ansible -m shell -a '。 /etc/profile.d/rh74enable.sh ; env' all --limit=mnXXX -vv 谢谢
      • “.”之间有空格和“/path/to/profile”。这 ”。”意思是“来源”
      【解决方案4】:

      当 ansible 将权限提升到 sudo 时,它不会调用 sudo 用户的登录 shell

      我们需要改变调用 sudo 的方式,比如使用 -i 和 -H 标志调用它

      "sudo_flags=-H" 在你的 ansible.cfg 文件中

      【讨论】:

      • 谢谢,但我不想在部署时将权限升级到 sudo。
      【解决方案5】:

      如果你能以root身份运行,你可以使用runuser。

      - shell: runuser -l '{{ install_user }}' -c "{{ cmd }}"

      这在新的登录 shell 中以 install_user 身份有效地运行命令,就好像您使用了 su - *install_user*(它会加载配置文件,尽管它可能是 .bash_profile 而不是 .profile。 ..) 然后执行*cmd*

      我会尽量不要以 root 身份运行所有内容,以便您可以以其他人身份运行它...

      【讨论】:

        【解决方案6】:

        如果您可以修改目标主机的配置并且不想更改您的 ansible yaml 代码。您可以试试这个:
        将变量 ENV_VAR=/usr/users/toto 添加到 /etc/environment 文件中而不是 ~/.profile

        【讨论】:

          【解决方案7】:
            shell: "bash -l scala -version"
          

          通过使用 bash -l 将允许 ansible 加载相应的 bash_profile。

          bash: '-i' (interactive shell) 不允许 ansible 运行其他任务。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-08-06
            • 1970-01-01
            • 2021-10-25
            • 1970-01-01
            • 2019-01-04
            • 1970-01-01
            相关资源
            最近更新 更多