แหล่งที่มา. bashrc ด้วย Ansible ไม่ได้


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เหมาะสมเมื่อคุณเรียกใช้ภายในเชลล์ที่มีอยู่ - รันคำสั่งในเชลล์นั้นและมีประโยชน์ / เป็นประโยชน์ก็ต่อเมื่อมีเชลล์ที่มีอยู่ซึ่งมีสถานะหรือการกำหนดค่าที่คุณต้องการเปลี่ยน เมื่อคุณเรียกใช้การกระทำเบิ้ลที่สร้างเปลือกใหม่ทั้งหมดและวิ่งคำสั่งภายในที่เปลือก - ดังนั้นคุณจะไม่ได้รับการปรับปรุงตัวแปรสภาพแวดล้อมในบริบทอื่น ๆ ดังนั้นมันจะไม่จริงมีประโยชน์ / effecet ใด ๆ เป็นเวลานาน แม้ว่าคุณจะทำให้สิ่งนี้ทำงานได้โดยไม่มีข้อผิดพลาด
Charles Duffy

@CharlesDuffy หากคุณต้องการรันคำสั่งที่คาดว่าจะมีการกำหนดตัวแปรสภาพแวดล้อมจากนั้นพยายามหาแหล่งที่มาเช่น. bashrc หรือ. bash_profile เพื่อกำหนดตัวแปรดังกล่าวเป็นกรณีการใช้งานที่ถูกต้องใช่หรือไม่
htellez

@htellez การรันsourceกำหนดตัวแปรตามระยะเวลาของเชลล์ที่รันเท่านั้น และเชลล์นั้นออกไปแล้ว (และตัวแปรที่กำหนดไว้หายไป) ตามเวลาที่คำสั่ง ansible ออกและคำสั่งถัดไปเริ่มทำงาน
Charles Duffy

@htellez, ... ดังนั้นคำตอบเดียวที่นี่มีประโยชน์จริง ๆ ในทางที่มีความหมายคือคำตอบของSteve Midgleyเนื่องจากคุณได้ทำอย่างอื่นในเปลือกเดียวกันที่วิ่งsourceก่อนที่มันจะออกไป
Charles Duffy

นั่นคือกรณีการใช้งานที่ฉันพยายามอธิบายฉันขอโทษถ้าฉันไม่ชัดเจน ฉันพยายามอธิบายสถานการณ์ที่คุณต้องการเรียกใช้สิ่งที่คาดว่าจะมีการกำหนดสภาพแวดล้อมเฉพาะ ฉันเข้าสู่เธรดนี้เพราะฉันได้รับข้อผิดพลาดเดียวกันและจากการอ่านคำตอบของสตีฟก็คือฉันตระหนักว่างานเชลล์ของ ansible ใช้ sh โดยค่าเริ่มต้นแทนที่จะเป็น bash การทำให้คำสั่งเป็นคำสั่ง bash ทำให้sourceทำงานได้อย่างชัดเจนในแบบที่คุณคุ้นเคยมากที่สุด
htellez

คำตอบ:


88

คุณมีสองตัวเลือกในการใช้แหล่งที่มากับ ansible หนึ่งคือด้วยคำสั่ง "shell:" และ / bin / sh (ค่าเริ่มต้น ansible) "source" เรียกว่า "." ใน / bin / sh. ดังนั้นคำสั่งของคุณจะเป็น:

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

โปรดทราบว่าคุณต้องรันคำสั่งหลังจากจัดหา. 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

สุดท้ายฉันจะทราบว่าคุณอาจต้องการแหล่งที่มา "/ etc / profile" จริงๆถ้าคุณใช้ Ubuntu หรือรุ่นที่คล้ายกันซึ่งจำลองการเข้าสู่ระบบภายในเครื่องได้อย่างสมบูรณ์


3
นอกจากนี้โปรดทราบว่าปัญหานี้ได้รับการยื่น (และแสดงความคิดเห็นโดยฉัน) เป็นคำขอข้อบกพร่อง / คุณสมบัติในแกน Ansible แต่ Ansible ปิดมันและพูดว่า "เขียนปลั๊กอิน" บาห์. github.com/ansible/ansible/issues/4854
Steve Midgley

1
คุณอ่านใจฉันหรือเปล่า? คุณตอบผีเสื้อ 3 ตัวที่แล้วและฉันคิดว่าจะแก้ไข.-> source- และคุณก็ทำทันที :)
warvariuc

ฉันลองแล้วsource "/etc/profile"- มันไม่ได้ผลสำหรับฉัน สิ่งนี้ได้ผล:source "~/.profile"
warvariuc

5
ฉันมีฟังก์ชัน bash ที่กำหนดไว้ภายใน. bashrc และหลังจากจัดหา. bashrc ฉันจะเรียกใช้งาน / เรียกใช้ฟังก์ชันเหล่านั้นได้อย่างไร ฉันพยายามและเป็นที่พูดว่าshell: . ~/.bashrc && nvm install {{ node_version }} nvm command not foundฉันจะแก้ปัญหานี้ได้อย่างไร?
RaviTezu

1
@RaviTezu: ปัญหาในกรณีของฉันเกิดจากบรรทัดต่อไปนี้ใน. bashrc: # ถ้าไม่ทำงานแบบโต้ตอบอย่าทำอะไรเลย $ - ใน i ) ;; *) กลับมา ;; esac นี่เป็นปัญหาอย่างน้อยใน ubuntu-16.04 xenial64 ที่. bashrc ไม่ทำงานบนเชลล์ที่ไม่ใช่แบบโต้ตอบซึ่งเป็นกรณีเมื่อเรียกใช้คำสั่งผ่าน ssh หากต้องการทดลองใช้ให้ตั้งค่า PATH ใน ~ / .bashrc และเรียกใช้ (สมมติว่าคุณได้ตั้งค่าพอร์ต 2222 ส่งต่อไปยัง 22 บนระบบปฏิบัติการผู้เยี่ยมชม): ssh -p 2222 ubuntu@127.0.0.1 'echo $ PATH' หากคำสั่งข้างต้นไม่ ' t แสดง PATH ที่คุณตั้งไว้ใน. bashrc จากนั้นแก้ไข. bashrc
Divick

24

ดังนั้นcommandจะเรียกใช้ไฟล์ปฏิบัติการเท่านั้น sourceต่อ se ไม่ใช่ปฏิบัติการ (เป็นคำสั่งเชลล์ในตัว) มีเหตุผลใดบ้างที่คุณต้องการsourceตัวแปรสภาพแวดล้อมแบบเต็ม?

มีวิธีอื่นในการรวมตัวแปรสภาพแวดล้อมใน Ansible ตัวอย่างเช่นenvironmentคำสั่ง:

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

อีกวิธีหนึ่งคือการใช้shellโมดูล Ansible:

- 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

งานเชลล์รับพารามิเตอร์เช่นนี้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

ฉันประสบปัญหาเดียวกันนี้เมื่อพยายามรับ 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 docs

2

ฉันลองทำตามคำตอบที่ระบุไว้ แต่ไม่ได้ผลสำหรับฉันในขณะที่ติดตั้งทับทิมผ่านrbenv 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
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

คำตอบจำนวนมากแนะนำไปที่ source ~ / .bashrc แต่ปัญหาหลักคือ ansible shell ไม่โต้ตอบและการใช้งาน ~ / .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'";

และนี่คือการทดสอบที่ตอบได้ :

- 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 เทียบกับ 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.