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, running 은에서 실행되는 셸 기간 동안source 만 변수 정의합니다 . 그리고 그 쉘은 ansible 명령이 종료되고 다음 명령이 시작될 때까지 종료되었습니다 (그리고 그것이 정의한 변수는 손실되었습니다).
Charles Duffy

@htellez, ... 따라서 실제로 의미있는 방식으로 유용한 유일한 대답은 Steve Midgley가 작성한 것입니다 . 왜냐하면 source종료하기 전에 실행 된 동일한 쉘에서 다른 작업을 수행 하기 때문입니다.
Charles Duffy

이것이 제가 설명하려고했던 사용 사례입니다. 명확하지 않으면 죄송합니다. 정의 된 특정 환경을 예상하는 무언가를 실행하려는 시나리오를 설명하려고했습니다. 나는 동일한 오류가 발생했기 때문에이 스레드에 도착했으며 Steve의 답변 을 읽음 으로써 ansible의 쉘 작업이 기본적으로 bash 대신 sh를 사용한다는 것을 깨달았습니다. 명령을 bash 명령으로 만들면 source가장 익숙한 방식으로 작동합니다.
htellez

답변:


88

ansible과 함께 소스를 사용하는 두 가지 옵션이 있습니다. 하나는 "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 트랜잭션에서 실행됩니다.

두 번째 옵션은 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

나는 시도했다 source "/etc/profile"-그것은 나를 위해 작동하지 않았다. 이 일을 :source "~/.profile"
warvariuc

5
.bashrc 내부와 .bashrc 소싱 후 일부 bash 함수가 정의되어 있습니다. 그 함수를 어떻게 실행 / 호출 할 수 있습니까? 나는 노력 shell: . ~/.bashrc && nvm install {{ node_version }}하고 있으며 말하고 nvm command not found있습니다. 어떻게 해결할 수 있습니까?
RaviTezu

1
@RaviTezu : 제 경우의 문제는 .bashrc의 다음 줄 때문이었습니다. # 대화 형으로 실행되지 않으면 아무것도하지 마십시오 case $-in i ) ;; *) 반환 ;; esac 이것은 적어도 ubuntu-16.04 xenial64의 문제입니다. 여기서 .bashrc는 ssh를 통해 명령을 실행할 때와 같은 비대화 형 셸에서 실행되지 않습니다. 그것을 시도하려면 ~ / .bashrc에 일부 PATH를 설정하고 실행하십시오 (게스트 OS에서 포트 2222를 22로 전달했다고 가정) : ssh -p 2222 ubuntu@127.0.0.1 'echo $ PATH'위 명령이 작동하지 않는 경우 ' t는 다음의 .bashrc 수정의 .bashrc에서 설정 한 PATH 보여
Divick

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에는 소스 commmand 만 있습니다. 그래서 shell source /home/username/.bashrc됩니다shell . /home/username/.bashrc
b1r3k 2014-12-05

쉘 태스크는 executable=/usr/bin/bash다음 과 같은 매개 변수를 사용합니다. 그런 다음 사용 가능한 경우 bash에서 실행합니다.
fgysin의 분석 재개 모니카

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

Ubuntu 서버에서 virtualenvwrapper를 작동 시키려고 할 때 이와 동일한 문제가 발생했습니다. 다음과 같이 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_ENVbash 문서에서 설명한대로 사용하고 싶을 것입니다 .

2

글쎄, 나열된 답변을 시도했지만 rbenv 통해 루비를 설치하는 동안 저에게 효과가 없었 습니다 . 나는 아래에서 줄을 구해야했다./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. 그러나, 내가 사용하는 것이 잔소리 become, become_method그리고 become_user대신에 ... 어쨌든 일하는 것이 그 "방법"PARAMS의 조합을 알아낼 수 없었다.
Yuri

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

위의 모든 옵션을 ansible 2.4.1.0으로 시도했으며 다른 두 개까지 아무도 작동하지 않으며 여기에 사례를 재현하는 세부 정보가 있습니다.

$ 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  

두 가지 옵션이 작동합니다.

  • shell: /bin/bash -ic 'ta'
  • shell: ssh -tt localhost /bin/bash -ci 'ta' 그러나 이것은 로컬에서 암호 입력이 필요합니다.

0

내 2 센트, 나는 소싱 문제를 일주 ~/.nvm/nvm.sh~/.profile다음 사용 sudo -iu등 다른 답변에 제안했다.

2018 년 1 월 대 Ubuntu 16.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.