.Bashrc'yi Ansible ile kaynaklamak mümkün değil


85

Uzak ana bilgisayara ssh yapabilirim ve bir source /home/username/.bashrc- her şey yolunda gider. Ancak yaparsam:

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

Alırım:

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

Neyi yanlış yaptığımı bilmiyorum ...


sourceyalnızca mevcut bir kabuk içinde çalıştırdığınızda anlamlıdır - komutları bu kabukta çalıştırır ve bu nedenle yalnızca durumunu veya yapılandırmasını değiştirmek istediğiniz mevcut bir kabuk olduğunda yararlı / yararlıdır. Yanıtlanabilir bir eylem çalıştırdığınızda, bu tamamen yeni bir kabuk oluşturur ve bu kabuk içinde bir komut çalıştırır - böylece ortam değişkenlerini başka herhangi bir bağlamda güncellemeyeceksiniz, bu nedenle aslında herhangi bir yararlı / kalıcı etkiye sahip olmayacaktır. , bunu hatasız çalıştırsanız bile.
Charles Duffy

@CharlesDuffy Ortam değişkenlerinin tanımlanmasını bekleyen bir komut yürütmek istiyorsanız, bu tür değişkenleri tanımlamak için .bashrc veya .bash_profile gibi bir şeyi kaynaklamaya çalışmak geçerli bir kullanım durumu değil mi?
htellez

@htellez, koşmak sourceyalnızca içinde çalıştığı kabuğun süresi boyunca değişkenleri tanımlar . Ve o kabuktan çıkıldı (ve tanımladığı değişkenler kayboldu), cevapsız bir komut çıkıp bir sonraki başladığında.
Charles Duffy

@htellez, ... bu nedenle, burada gerçekten anlamlı herhangi bir şekilde yararlı olan tek cevap Steve Midgley tarafından verilen cevaptır , çünkü siz sourceçıkmadan önce çalışan aynı kabukta başka bir şey yapmanıza neden olur.
Charles Duffy

Tanımlamaya çalıştığım kullanım durumu tam olarak buydu, net olamadıysam özür dilerim. Belirli bir ortamın tanımlanmasını bekleyen bir şeyi çalıştırmak istediğiniz bir senaryoyu anlatmaya çalıştım. Bu konuya ulaştım çünkü aynı hatayı alıyorum ve Steve'in cevabını okuyarak, cevaplayıcının kabuk görevinin bash yerine varsayılan olarak sh kullandığını fark ettim. Komutu bir bash komutu yapmak, sourceçalışmayı açıkça alışık olduğunuz şekilde yapar .
htellez

Yanıtlar:


88

Kaynak ile yanıtlayıcı kullanmak için iki seçeneğiniz vardır. Bunlardan biri "shell:" komutu ve / bin / sh (yanıtlanabilir varsayılan) ile. "kaynak", "" olarak adlandırılır. / bin / sh. Yani emriniz şöyle olacaktır:

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

.Bashrc b / c kaynağını kullandıktan sonra bir komut çalıştırmanız gerektiğini unutmayın, her ssh oturumu farklıdır - her yanıtlanabilir komut ayrı bir ssh işleminde çalışır.

İkinci seçeneğiniz Ansible kabuğunu bash kullanmaya zorlamaktır ve ardından "kaynak" komutunu kullanabilirsiniz:

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

Son olarak, Ubuntu veya benzerindeyseniz, aslında "/ etc / profile" kaynak yapmak isteyebileceğinizi not edeceğim, bu daha tamamen yerel bir girişi simüle eder.


3
Ayrıca bu sorunun Ansible çekirdeğinde bir hata / özellik isteği olarak dosyalandığını (ve benim tarafımdan yorumlandığını) unutmayın. Ama Ansible onu kapattı ve "bir eklenti yaz" dedi. Bah. github.com/ansible/ansible/issues/4854
Steve Midgley

1
Aklımı mı okuyorsun Bunu 3 ay önce cevapladınız ve bunu düzenlemeyi düşünüyordum .-> source- ve hemen bunu yaptınız :)
warvariuc

Denedim source "/etc/profile"- benim için işe yaramadı. Bu işe yaradı:source "~/.profile"
warvariuc

5
.Bashrc içinde ve .bashrc'yi sağladıktan sonra tanımlanmış bazı bash işlevlerim var. bu işlevleri nasıl çalıştırabilirim / çağırabilirim? Deniyorum shell: . ~/.bashrc && nvm install {{ node_version }}ve diyor ki nvm command not found,. Bunu Nasıl Çözebilirim?
RaviTezu

1
@RaviTezu: Benim durumumdaki sorun .bashrc'deki aşağıdaki satırlardan kaynaklanıyordu: # Etkileşimli olarak çalışmıyorsa, hiçbir şey yapmayın case $ - in i ) ;; *) dönüş;; esac Bu, en azından ubuntu-16.04 xenial64'te .bashrc'nin etkileşimli olmayan kabuklarda çalıştırılmadığı bir sorundur, bu durum ssh aracılığıyla komutları çalıştırırken olduğu gibi. Denemek için ~ / .bashrc içinde bir PATH ayarlayın ve çalıştırın (2222 numaralı bağlantı noktasını konuk işletim sisteminde 22'ye yönlendirdiğiniz varsayılarak): ssh -p 2222 ubuntu@127.0.0.1 'echo $ PATH' Yukarıdaki komut çalışmazsa ' t
.bashrc'de

24

Bu nedenle commandyalnızca çalıştırılabilir dosyalar çalıştırılır. sourcekendi başına bir yürütülebilir dosya değildir. (Bu yerleşik bir kabuk komutudur). sourceTam bir ortam değişkeni istemenizin herhangi bir nedeni var mı ?

Ansible'a ortam değişkenlerini dahil etmenin başka yolları da vardır. Örneğin environmentdirektif:

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

Başka bir yol shellAnsible modülünü kullanmaktır :

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

veya

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

Bu durumlarda, Ansible adımı çalıştırıldığında kabuk örneği / ortamı sona erecektir.


2
neredeyse iyi, ne yazık ki / bin / sh yalnızca kaynak komutuna sahip değil. so shell source /home/username/.bashrcolurshell . /home/username/.bashrc
b1r3k

Kabuk görevi şu şekilde bir parametre alır: executable=/usr/bin/basheğer mevcutsa, daha sonra onu bash içinde çalıştırır.
fgysin Monica'yı yeniden görevlendirecek

16

Bu cevabın çok geç geldiğini biliyorum ama yeterince kodda sudo seçeneğini kullanabileceğinizi gördüm -i :

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

Belgelerde söylendiği gibi

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'ı bir Ubuntu sunucusunda çalıştırmaya çalışırken aynı sorunu yaşıyordum. Ansible'ı şu şekilde kullanıyordum:

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

ancak kaynak komutu çalışmıyordu.

Sonunda .bashrc dosyasının, Ansible tarafından çağrıldığında kaynağın çalışmasını engelleyen dosyanın üstünde birkaç satır olduğunu keşfettim:

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

Bu satırları .bashrc'de yorumladım ve bundan sonra her şey beklendiği gibi çalıştı.


Bu, çoğu .bashrcdosya için tamamen makul ve standart bir başlıktır . Muhtemelen farklı bir kabuk dosyasını kaynaklamak veya BASH_ENVbash belgelerinde anlatıldığı gibi kullanmak istersiniz .

2

Listelenen cevapları denedim ama rbenv aracılığıyla ruby'yi kurarken bunlar benim için işe yaramadı . Aşağıdaki satırlardan kaynak yapmak zorunda kaldım/root/.bash_profile

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

Sonunda bunu buldum

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

Bunu herhangi bir komutla kullanabilirsiniz.

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

1
Bu klasik yaklaşım Ansible ile çalışır 2.2.0.0. Ancak, ben kullanması gerektiğini nags become, become_methodve become_userbunun yerine ... Neyse çalışacak olanlar "yöntemi" params bir arada çözemedim.
Yuri

2

En iyi çözüm olduğunu buldum:

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

Kullanıcıyı ekleyerek değiştirebilirsiniz (varsayılan: kök):

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

Daha fazla bilgi burada: Ansible


2

Pek çok yanıt ~ / .bashrc'yi kaynaklamayı önerir, ancak asıl sorun, yanıtlanabilir kabuğun etkileşimli olmaması ve ~ / .bashrc uygulamasının varsayılan olarak etkileşimli olmayan kabuğu yok saymasıdır (başlangıcını kontrol edin).

Bulduğum ssh etkileşimli oturum açma işleminden sonra komutları kullanıcı olarak yürütmek için en iyi çözüm şudur:

- 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' etkileşimli kabuk anlamına gelir, bu nedenle .bashrc göz ardı edilmeyecektir '-l', tam kullanıcı profilini oluşturan oturum açma kabuğu anlamına gelir


0

Yukarıdaki tüm seçenekleri yanıtlanabilir 2.4.1.0 ile denedim ve kimse diğer ikisine kadar çalışmıyor ve işte kasayı yeniden üretmek için ayrıntı.

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

Ve bu cevaplanabilir bir test :

- 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

Ve sonuç bu:

$ 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  

Çalışılan iki seçenek vardır:

  • shell: /bin/bash -ic 'ta'
  • shell: ssh -tt localhost /bin/bash -ci 'ta' ancak bu, yerel olarak şifre girişi gerektirir.

0

Benim 2 cent i kaynak sorunu circumnavigated ~/.nvm/nvm.shiçine ~/.profileve daha sonra kullanarak sudo -iubaşka cevap önerdi.

Ocak 2018'de Ubuntu 16.04.5'e karşı denendi

- 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

Doğru yol şu şekilde olmalıdır:

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

Not: ansible 2.0.2sürümde test edilir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.