Ansibleで.bashrcを調達することはできません


85

リモートホストにSSHで接続して、source /home/username/.bashrcすべてを正常に実行できます。しかし私がそうするなら:

- name: source bashrc
  sudo: no
  action: command source /home/username/.bashrc

私は得る:

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

何が間違っているのかわかりません...


source既存のシェル内で実行する場合にのみ意味があります。そのシェルでコマンドを実行するため、状態または構成を変更する既存のシェルがある場合にのみ役立ちます。ansibleアクションを実行すると、まったく新しいシェル作成され、そのシェル内コマンドが実行されます。そのため、他のコンテキストで環境変数を更新することはないため、実際には有用で永続的な効果はありません。 、これをエラーなしで実行したとしても。
Charles Duffy

@CharlesDuffy環境変数が定義されることを期待するコマンドを実行したい場合は、.bashrcや.bash_profileなどをソースにして、そのような変数を定義しようとするのが有効なユースケースではありませんか?
htellez

@ htellez、runningsourceは、実行するシェルの期間中の変数のみを定義します。そして、そのシェルは、ansibleコマンドが終了して次のコマンドが開始されるまでに終了しました(そしてそれが定義する変数は失われました)。
チャールズダフィー

@ htellez、...したがって、意味のある方法で実際に役立つ唯一の答えは、Steve Midgleyによるものですsource。これは、実行されたのと同じシェルで、終了する前に何か他のことをしているためです。
チャールズダフィー

それはまさに私が説明しようとしたユースケースです。はっきりしなかった場合は申し訳ありません。特定の環境が定義されていることを期待する何かを実行したいシナリオを説明しようとしました。同じエラーが発生したため、このスレッドにアクセスしました。Steveの回答を読むと、ansibleのシェルタスクがデフォルトでbashではなくshを使用していることがわかりました。コマンドをbashコマンドにすることで、通常sourceの方法で作業を明示的に行うことができます。
htellez

回答:


88

ansibleでソースを使用するには2つのオプションがあります。1つは、「shell:」コマンドと/ bin / sh(ansibleのデフォルト)を使用する方法です。「ソース」は「」と呼ばれます。/ bin / shにあります。したがって、コマンドは次のようになります。

- name: source bashrc
  sudo: no   
  shell: . /home/username/.bashrc && [the actual command you want run]

.bashrc b / cをソーシングした後にコマンドを実行する必要があることに注意してください。各sshセッションは個別です。すべてのansibleコマンドは、個別のsshトランザクションで実行されます。

2番目のオプションは、Ansibleシェルにbashの使用を強制することです。その後、「source」コマンドを使用できます。

- name: source bashrc
  sudo: no   
  shell: source /home/username/.bashrc && [the actual command you want run]
  args:
     executable: /bin/bash

最後に、Ubuntuなどを使用している場合は、実際に「/ etc / profile」を入手することをお勧めします。これにより、ローカルログインがより完全にシミュレートされます。


3
また、この問題はAnsibleコアのバグ/機能リクエストとして提出された(そして私がコメントした)ことに注意してください。しかし、Ansibleはそれを閉じて、「プラグインを書く」と言いました。ああ。github.com/ansible/ansible/issues/4854
Steve Midgley

1
あなたは私の心を読んでいますか?あなたはこれに3か月前に答えました、そして私はこれを編集することを考えていました.-> source-そしてあなたはすぐにこれをしました:)
warvariuc 2015年

私は試しましたsource "/etc/profile"-それは私にとってはうまくいきませんでした。これはsource "~/.profile"
うまくいき

5
.bashrc内で、.bashrcをソーシングした後にいくつかのbash関数を定義しています。これらの関数を実行/呼び出すにはどうすればよいですか?私はしようshell: . ~/.bashrc && nvm install {{ node_version }}としています、そしてそれは言っています、nvm command not found。どうすればこれを解決できますか?
RaviTezu 2016年

1
@RaviTezu:私の場合の問題は、.bashrcの次の行が原因でした:#インタラクティブに実行されていない場合は、何もしないでください$ -in i);; *)戻る;; esacこれは少なくともubuntu-16.04xenial64の問題であり、sshを介してコマンドを実行する場合のように、.bashrcが非対話型シェルで実行されません。試してみるには、〜/ .bashrcにPATHを設定して実行します(ゲストOSでポート2222を22に転送するように設定していると仮定します):ssh -p 2222 ubuntu@127.0.0.1'echo $ PATH '上記のコマンドが実行しない場合' t .bashrcに設定したPATHを表示してから、.bashrcを修正します
Divick 2017

24

したがってcommand、実行可能ファイルのみを実行します。 sourceそれ自体は実行可能ファイルではありません。(これは組み込みのシェルコマンドです)。source完全な環境変数にしたい理由はありますか?

Ansibleに環境変数を含める方法は他にもあります。たとえば、environmentディレクティブ:

- name: My Great Playbook
  hosts: all
  tasks:
    - name: Run my command
      sudo: no
      action: command <your-command>
      environment:
          HOME: /home/myhome

別の方法は、shellAnsibleモジュールを使用することです。

- name: source bashrc
  sudo: no
  action: shell source /home/username/.bashrc && <your-command>

または

- name: source bashrc
  sudo: no   
  shell: source /home/username/.bashrc && <your-command>

このような場合、Ansibleステップが実行されると、シェルインスタンス/環境は終了します。


2
ほぼ良好ですが、残念ながら/ bin / shにはソースコマンドのみがありません。そうshell source /home/username/.bashrcなったshell . /home/username/.bashrc
b1r3k

シェルタスクは、そのようなパラメーターを受け取りますexecutable=/usr/bin/bash。それが利用可能な場合は、bashで実行します。
–fgysinは2015

16

この答えが遅すぎることは知っていますが、十分なコードでsudoオプションを使用できることを確認しまし-i た。

- name: source bashrc
  shell: sudo -iu {{ansible_user_id}} [the actual command you want run]

ドキュメントで述べたように

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.

5

virtualenvwrapperをUbuntuサーバーで動作させようとしたときに、これと同じ問題が発生していました。私は次のようにAnsibleを使用していました:

- name: Make virtual environment
  shell: source /home/username/.bashrc && makevirtualenv virenvname
  args:
    executable: /bin/bash

しかし、ソースコマンドは機能していませんでした。

最終的に、.bashrcファイルのファイルの先頭に数行あり、Ansibleによって呼び出されたときにソースが機能しないことを発見しました。

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

私は.bashrcでそれらの行をコメントアウトし、その後すべてが期待どおりに機能しました。


これは、ほとんどの.bashrcファイルにとって完全に合理的で標準的なヘッダーです。別のシェルファイルを入手するかBASH_ENV、bashのドキュメントで説明されているように使用することをお勧めします。

2

さて、私はリストされた答えを試しましたが、rbenvを介してrubyをインストールしている間、それらは私のために機能しませんでした。私は以下の行をから調達しなければなりませんでした/root/.bash_profile

PATH=$PATH:$HOME/bin:$HOME/.rbenv/bin:$HOME/.rbenv/plugins/ruby-build/bin
export PATH
eval "$(rbenv init -)"

最後に、私はこれを思いついた

- shell: sudo su - root -c 'rbenv install -v {{ ruby_version }}'

これはどのコマンドでも使用できます。

- shell: sudo su - root -c 'your command'

1
この古典的なアプローチはAnsibleで機能し2.2.0.0ます。しかし、それは私が使用する必要があることをしつこくしますbecomebecome_methodそしてbecome_user代わりに...私はとにかく機能するそれらの「メソッド」パラメータの組み合わせを理解することができませんでした。
百合

2

私は最良の解決策になることがわかりました:

- name: Source .bashrc
  shell: . .bashrc
  become: true

追加することでユーザーを変更できます(デフォルト:root):

- name: Source .bashrc
  shell: . .bashrc
  become: true
  become-user: {your_remote_user}

詳細はこちら:Ansibleになる


2

多くの回答が〜/ .bashrcをソースすることを推奨していますが、主な問題は、ansibleシェルがインタラクティブではなく、〜/ .bashrcの実装がデフォルトで非インタラクティブシェルを無視することです(最初を確認してください)。

私が見つけた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'はインタラクティブシェルを意味するため、.bashrcは無視されません '-l'は完全なユーザープロファイルを取得するログインシェルを意味します


0

上記のすべてのオプションをansible2.4.1.0で試しましたが、次の2つまで誰も機能しません。ここに、ケースを再現するための詳細を示します。

$ cat ~/.bash_aliases 
alias ta="echo 'this is test for ansible interactive shell'";

そしてこれは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

そしてこれが結果です:

$ 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  

動作する2つのオプションがあります。

  • shell: /bin/bash -ic 'ta'
  • shell: ssh -tt localhost /bin/bash -ci 'ta' ただし、これにはローカルでのパスワード入力が必要です。

0

私の2セントは、別の回答で提案されているように、調達~/.nvm/nvm.sh~/.profileて使用する問題を一周しましたsudo -iu

2018年1月とUbuntu16.04.5で試してみました

- name: Installing Nvm 
  shell: >
    curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
  args:
    creates: "/home/{{ ansible_user }}/.nvm/nvm.sh"
  tags:
    - nodejs    

- name: Source nvm in ~/.profile
  sudo: yes
  sudo_user: "{{ ansible_user }}"
  lineinfile: >
    dest=~/.profile
    line="source ~/.nvm/nvm.sh"
    create=yes
  tags: 
    - nodejs
  register: output    

- name: Installing node 
  command: sudo -iu {{ ansible_user }} nvm install --lts
  args:
     executable: /bin/bash
  tags:
    - nodejs    

-3

正しい方法は次のとおりです。

- hosts: all
  tasks:
    - name: source bashrc file
      shell: "{{ item }}"
      with_items:
         - source ~/.bashrc
         - your other command

注:ansible 2.0.2バージョンでのテストです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.