Không thể tìm thấy lỗi với / bin / sh: 1: / usr / bin / python: không tìm thấy


187

Tôi đang gặp phải một lỗi mà tôi chưa từng thấy trước đây. Đây là lệnh và lỗi:

$ ansible-playbook create_api.yml

PLAY [straw] ******************************************************************

GATHERING FACTS ***************************************************************
failed: [104.55.47.224] => {"failed": true, "parsed": false}
/bin/sh: 1: /usr/bin/python: not found


TASK: [typical | install required system packages] *****************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/Users/john/create_api.retry

104.55.47.224               : ok=0    changed=0    unreachable=0    failed=1

Đây là tập tin create_api.yml:

---

- hosts: api
  remote_user: root
  roles:
    - api

Và đây là tập tin máy chủ:

[api]
104.55.47.224

Tôi có thể loại bỏ phần vai trò và nó sẽ không được đưa vào TASK đầu tiên, thay vào đó, nó sẽ làm cho nó chỉ làm cho nó thành dòng /bin/sh: 1: /usr/bin/python: not found. Điều gì có thể xảy ra ở đây?


LƯU Ý: Trong trường hợp bất kỳ ai đang ping địa chỉ IP và không nhận được phản hồi, bạn nên biết rằng tôi đã thay đổi địa chỉ IP kể từ khi dán mã.

Con trăn EDIT đã được cài đặt cục bộ, vấn đề là nó không được cài đặt trên máy từ xa đang chạy Ubuntu 15.04

Câu trả lời:


171

Tôi đã vấp phải lỗi này khi chạy ansible trên máy chủ Ubuntu 15.10 , bởi vì nó xuất hiện với Python 3.4.3ansible yêu cầu Python 2 .

Đây là provision.ymlvẻ ngoài của tôi bây giờ:

- hosts: my_app
  sudo: yes
  remote_user: root
  gather_facts: no
  pre_tasks:
    - name: 'install python2'
      raw: sudo apt-get -y install python

  tasks:
    - name: 'ensure user {{ project_name }} exists'
      user: name={{ project_name }} state=present
  • Đừng quên tùy chọn -y (nói có với tất cả các câu hỏi) với apt-get (hoặc mô-đun thô sẽ bị mắc kẹt trong âm thầm)

  • gather_facts: no dòng này cũng rất quan trọng (vì chúng ta không thể thu thập dữ kiện mà không có trăn)


12
Vì vậy, sau đó các vai trò tiếp theo không thể sử dụng sự thật ... có cách nào để thu thập lại sự thật không? aha, stackoverflow.com/questions/31054453/...
stephen

16
Lưu ý rằng dòng'ather_facts: no ' cũng rất quan trọng.
RCreswick

6
@ surfer190 tìm tuyệt vời! Tôi cũng thấy rằng việc thêm action: setuplàm pre_task cuối cùng cũng hoạt động rất tốt :)
mrooney

1
@ surfer190 xem câu trả lời của tôi ở đây nếu bạn đang sử dụng EC2 với ansible, bạn có thể sử dụng CloudInit để cài đặt python2 để bạn có thể sử dụng thu thập thông tin như bình thường.
Miroslav

1
Trong trường hợp bất cứ ai cũng thắc mắc, không cần thiết phải chạy rawtác vụ để cài đặt Python 2 vào pre_tasks; taskshoạt động tốt thường xuyên quá. Nhưng đặt nó vào pre_tasks, với một nhiệm vụ khác để gọi setupmô-đun Ansible , sẽ đảm bảo các sự kiện có sẵn cho bất kỳ vai trò nào được gán cho máy chủ.
Kenny Evitt

125

Ansible 2.2 có tính năng xem trước công nghệ hỗ trợ Python 3. Để tận dụng lợi thế này (vì vậy bạn không phải cài đặt Python 2 trên Ubuntu 16.04), chỉ cần đặt ansible_python_interpretertùy chọn cấu hình thành /usr/bin/python3. Điều này có thể được thực hiện trên cơ sở mỗi máy chủ trong tệp kho của bạn:

[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3

Tôi đã thử thêm / usr / bin / python vào biến này, nhưng nó không hoạt động. Thay vào đó, việc thêm python3 đã hoạt động và vấn đề này đã được khắc phục
Deep LF

97

Giải pháp 1:

Nếu bạn đang sử dụng Ansible >2.2.0, bạn có thể đặt ansible_python_interpretertùy chọn cấu hình thành /usr/bin/python3:

ansible my_ubuntu_host -m ping -e 'ansible_python_interpreter=/usr/bin/python3'

hoặc trong tệp kiểm kê của bạn:

[ubuntu_hosts]
<xxx.xxx.xxx.xxx>

[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

Giải pháp 2:

Nếu bạn đang sử dụng Ansible <2.2.0thì bạn có thể thêm chúng pre_tasksvào playbook của mình:

gather_facts: False
pre_tasks:
  - name: Install python for Ansible
    raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
    register: output
    changed_when: output.stdout != ""
    tags: always
  - setup: # aka gather_facts

CẬP NHẬT Với ansible 2.8.x, bạn không cần phải lo lắng về điều đó, nó hoạt động tốt với python> 3.5 cho cả bộ điều khiển và máy đích


Nếu bạn chạy Playbook bằng thẻ, hãy đảm bảo bạn thêm thẻ: luôn luôn vào tác vụ thiết lập - nếu không thì sẽ không thu thập được sự thật khi bạn sử dụng thẻ.
I Muff Bajescu

16
Tôi có ansible 2.3.0.0và nó không hoạt động ra khỏi hộp. Lỗi tương tự như được đăng bởi OP.
Bộ giải mã

Trong trường hợp điều này không rõ ràng rõ ràng, bạn phải thêm tệp này vào tệp kho lưu trữ của máy chủ, không phải vào một vars đi kèm, nghĩa là, nó nằm trong cùng một tệp kho lưu trữ như địa chỉ / tên máy chủ lưu trữ.
Shawn Mehan

32

Bạn có thể sử dụng mô-đun thô để cài đặt Python trên các máy chủ từ xa:

- raw: sudo apt-get install python-simplejson

11
Để đảm bảo điều này được gọi trước các nhiệm vụ trong vai trò của bạn và trước mọi phụ thuộc trong tệp meta của bạn, hãy thêm nó như thế này vào sổ chơi của bạn: pre_tasks: - raw: sudo apt-get install python-simplejson
Laurens Rietveld

5
Lưu ý rằng trong một playbook, bạn cũng phải vô hiệu hóa hái_facts, nếu không sẽ chạy lệnh thô. (tập hợp_facts: không)
RCreswick

@rcreswick Đó là vấn đề của tôi và giải pháp của bạn đã làm việc cho tôi. Cám ơn rất nhiều. Tôi đặt dòng "ather_facts: no "trong tệp .yml chính của mình (setup-ansible.yml) và thực thi playbook bằng lệnh này:" ansible-playbook -i lưu trữ setup-ansible.yml --flush-cache -vvvvvv -kK ". Tôi đã sử dụng các tùy chọn "-kK" với ansible-playbook vì cài đặt Ubuntu mặc định cần mật khẩu để thực hiện "sudo".
Ali Yousefi Sabzevar

Tại sao bạn cài đặt Simplejson chứ không phải pytghon mà lại nói về việc cài đặt python?
Henning

@Henning python-simplejsonđược viết bằng Python và do đó yêu cầu Python. Simplejson cũng là một yêu cầu cho hầu hết các mô-đun lõi Ansible. Bằng cách cài đặt python-simplejsonthông qua apt-get/ yumbạn cũng cài đặt Python và do đó bao gồm tất cả các phụ thuộc Ansible cơ bản ...
udondan

18

Để tóm tắt câu trả lời của người khác, đây là các cài đặt kết hợp phù hợp với tôi:

 - hosts: all
   become: true
   gather_facts: false

   # Ansible requires python2, which is not installed by default on Ubuntu Xenial
   pre_tasks:
     - raw: sudo apt-get -y install python-simplejson
     # action: setup will gather facts after python2 has been installed
     - action: setup

14

Cá nhân tôi đã tìm thấy 3 giải pháp khả thi cho vấn đề này hoạt động tốt trong các tình huống khác nhau:

Tùy chọn 1 - Đặt ansible_python_interpreter: /usr/bin/python3cho các máy chủ đã python3được cài đặt theo mặc định

Tôi nghĩ rằng đây là phương pháp ưu việt để giải quyết vấn đề nếu bạn có cách để nhóm các máy chủ của mình python3bằng cách mặc định chúng có được cài đặt hay không . Theo như tôi biết, python3có sẵn trên tất cả các phiên bản Ubuntu 16.04 trở lên.

  • Nếu tất cả các máy chủ của bạn chắc chắn có python3, bạn có thể thêm biến vào group_vars/all.yml(hoặc tương đương):
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
  • Nếu một số máy chủ của bạn không có python3và bạn có cách gắn thẻ chúng khi sử dụng khoảng không quảng cáo động (ví dụ: gắn thẻ AWS cho ec2.py), bạn có thể áp dụng biến cho một số máy chủ nhất định như sau:
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3
  • Nếu bạn sử dụng khoảng không quảng cáo tĩnh và có thể nhóm các máy chủ dựa trên việc chúng có hay không python3, bạn có thể làm một cái gì đó như thế này:
# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

[python3_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

Tôi thích tùy chọn này nhất vì nó không yêu cầu thay đổi trên máy chủ từ xa và chỉ thay đổi nhỏ đối với các biến, trái ngược với tùy chọn 2 và 3, yêu cầu bổ sung cho mọi playbook.

Tùy chọn 2 - Cài đặt Python 2 bằng cách sử dụng raw

Tùy chọn này yêu cầu đặt một phát ở đầu mỗi playbook có gather_facts: falsesử dụng rawđể cài đặt python:

- name: install python2 on all instances
  hosts: "*"
  gather_facts: false
  tasks:
    - name: run apt-get update and install python
      raw: "{{ item }}"
      loop:
        - sudo apt-get update
        - sudo apt-get -y install python
      become: true
      ignore_errors: true

ignore_errors: truelà bắt buộc nếu bạn có kế hoạch chạy phát trên các máy chủ chưa apt-getcài đặt (ví dụ: mọi thứ dựa trên RHEL), nếu không chúng sẽ bị lỗi trong lần phát đầu tiên.

Giải pháp này hoạt động, nhưng là thấp nhất trong danh sách của tôi vì một vài lý do:

  1. Cần phải đi đầu mỗi cuốn sách (trái ngược với tùy chọn 1)
  2. Giả định aptlà trên hệ thống và bỏ qua lỗi (trái ngược với tùy chọn 3)
  3. apt-get các lệnh chậm (trái ngược với tùy chọn 3)

Tùy chọn 3 - Symlink /usr/bin/python -> /usr/bin/python3sử dụngraw

Tôi chưa thấy giải pháp này được đề xuất bởi bất cứ ai khác. Điều đó không lý tưởng, nhưng tôi nghĩ nó vượt trội so với lựa chọn 2 theo nhiều cách. Đề nghị của tôi là sử dụng rawđể chạy lệnh shell để symlink /usr/bin/python -> /usr/bin/python3nếu python3có trên hệ thống python không:

- name: symlink /usr/bin/python -> /usr/bin/python3
  hosts: "*"
  gather_facts: false
  tasks:
    - name: symlink /usr/bin/python -> /usr/bin/python3
      raw: |
        if [ -f /usr/bin/python3 ] && [ ! -f /usr/bin/python ]; then
          ln --symbolic /usr/bin/python3 /usr/bin/python; 
        fi
      become: true

Giải pháp này tương tự như tùy chọn 2 ở chỗ chúng ta cần đặt nó ở đầu mỗi cuốn sách, nhưng tôi nghĩ nó vượt trội theo một số cách:

  • Chỉ tạo liên kết tượng trưng trong trường hợp cụ thể python3có mặt và pythonkhông - nó sẽ không ghi đè Python 2 nếu nó đã được cài đặt
  • Không giả định aptđược cài đặt
  • Có thể chạy với tất cả các máy chủ mà không cần xử lý lỗi đặc biệt
  • Là siêu nhanh so với bất cứ điều gì với apt-get

Rõ ràng nếu bạn cần cài đặt Python 2 tại /usr/bin/python, giải pháp này là không nên và tùy chọn 2 là tốt hơn.

Phần kết luận

  • Tôi đề nghị sử dụng tùy chọn 1 trong mọi trường hợp nếu bạn có thể.
  • Tôi khuyên bạn nên sử dụng tùy chọn 3 nếu kho lưu trữ của bạn thực sự lớn / phức tạp và bạn không có cách nào để dễ dàng nhóm các máy chủ lưu trữ python3, khiến tùy chọn 1 trở nên khó khăn và dễ bị lỗi hơn nhiều.
  • Tôi chỉ đề xuất tùy chọn 2 trên tùy chọn 3 nếu bạn cần cài đặt Python 2 tại /usr/bin/python.

Nguồn


13

Bạn cần python 2.7 để chạy Ansible. Trên Ubuntu 16.04, bạn có thể cài đặt nó thông qua lệnh này:

sudo apt-get install python-minimal

Sau đó, tôi có thể chạy

ansible-playbook -i inventories/staging playbook.yml

Chạy ansible thành công

Vui lòng kiểm tra thêm tại Sử dụng ansible trên Ubuntu 16.04


12

Những gì tôi đã sử dụng để làm việc này trên Ubuntu 15.10 trên một giọt Digital Ocean mới:

# my-playbook.yml
- name: python2
  hosts: test
  gather_facts: no
  pre_tasks:
    - raw: sudo apt-get -y install python-simplejson

$ ansible-playbook path/to/my-playbook.yml

Đối với Ubuntu 16.04 trên ổ SSD OVH mới, tôi đã phải nâng cấp apt-get trước khi các gói python2 có sẵn.


8

Tôi phát hiện ra rằng thực sự có thể có nhiều lần phát trong một vở kịch, vì vậy thiết lập của tôi hiện có một trò chơi "cung cấp phụ thuộc" chạy trên tất cả các máy chủ và các lần phát khác cho các máy chủ cụ thể. Vì vậy, không còn nữa pre_tasks.

Ví dụ:

- name: dependency provisioning
  hosts: all
  become: yes
  become_method: sudo
  gather_facts: false
  tasks:
    - name: install python2
      raw: sudo apt-get -y install python-simplejson

- name: production
  hosts: production_host
  roles:
    - nginx
  tasks:
    - name: update apt cache
      apt: update_cache=yes cache_valid_time=3600
  # ....

- name: staging
  hosts: staging_host
  roles:
    - nginx
  tasks:
    - name: update apt cache
      apt: update_cache=yes cache_valid_time=3600
  # ....

6

Như những người khác nói, điều này là do mất python2. Câu trả lời khác ở đây cung cấp một workaround với pre_tasksgather_facts: no, tuy nhiên nếu bạn đang ở trên EC2 và bạn quay lên trường hợp với ansible bạn có thể sử dụng user_datatùy chọn:

- ec2:
    key_name: mykey
    instance_type: t2.micro
    image: ami-123456
    wait: yes
    group: webserver
    count: 3
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes
    user_data: |
      #!/bin/bash
      apt-get update
      apt-get install -y python-simplejson
    register: ec2

Sau đó mọi người thường đợi ssh có sẵn như thế này:

  - name: "Wait for the instances to boot and start ssh"
    wait_for:
      host: "{{item.public_ip}}"
      port: 22
      delay: 5
      timeout: 300
    with_items: "{{ ec2.tagged_instances }}"
    when: ec2|changed

Tuy nhiên, tôi đã phát hiện ra rằng điều này không phải lúc nào cũng đủ lâu vì CloudInit được thực thi khá muộn trong quá trình khởi động nên python2 vẫn có thể không được cài đặt ngay sau khi ssh khả dụng. Vì vậy, tôi đã thêm một khoảng dừng trong trường hợp cá thể vừa được tạo:

  - name: "Wait for cloud init on first boot"
    pause: minutes=2
    when: ec2|changed

Điều này sẽ thực hiện công việc một cách hoàn hảo và như một lợi thế mà bạn không kiểm tra python2 trên mỗi lần chạy và bạn không phải thực hiện bất kỳ cách giải quyết nào để thu thập dữ kiện sau này.

Tôi chắc chắn rằng các nhà cung cấp đám mây khác cung cấp chức năng CloudInit tương tự, vì vậy hãy điều chỉnh cho trường hợp sử dụng của bạn.


3

Sử dụng Packer có thể thấy giải pháp dưới đây hữu ích

giả sử rằng bạn sử dụng nhà cung cấp có thể đóng gói của trình đóng gói, cấu hình của bạn có thể trông như dưới đây

trước tiên bạn có thể cài đặt python bằng trình cung cấp shell sau đó định cấu hình tùy chọn ansible_python_intepreter như hiển thị bên dưới

"provisioners": [
    {
      "type": "shell",
      "inline": [
        "apk update && apk add --no-cache python python-dev ansible bash"
      ]
    },
    {
      "type": "ansible-local",
      "playbook_file": "playbooks/your-play-book.yml",
      "playbook_dir": "playbooks",
      "extra_arguments": [
        "-e",
        "'ansible_python_interpreter=/usr/bin/python3'",
        "-vvv"
      ]
    },

2

Theo mặc định, Ansible yêu cầu Python 2 , tuy nhiên, Ansible 2.2+ cũng có thể hoạt động với Python 3 .

Vì vậy, hoặc cài đặt Python 2 bằng cách sử dụng rawmô-đun , ví dụ:

ansible localhost --sudo -m raw -a "yum install -y python2 python-simplejson"

hoặc đặt ansible_python_interpreterbiến trong tệp kiểm kê, như:

[local]
localhost ansible_python_interpreter="env python3"

Đối với Docker, bạn có thể thêm dòng sau:

RUN printf '[local]\r\nlocalhost ansible_python_interpreter="env python3"\r\n' > /etc/ansible/hosts

hoặc chạy nó dưới dạng:

ansible-playbook /ansible/provision.yml -e 'ansible_python_interpreter=/usr/bin/python3' -c local

1

Theo Gist này, bạn có thể cài đặt Python2 trên Ubuntu 16.04 như sau:

enter code here
gather_facts: False
pre_tasks:
  - raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
  - setup: # aka gather_facts

tasks:
  # etc. etc.

1

Rất nhiều câu trả lời .. Cảm ơn bạn đã đăng bài khi tôi bắt đầu từ trang này!

Tôi đã thực hiện một số hoạt động đào và nó rất ổn định với Ubuntu 14.04LTS, Ubuntu 15.04LTS dường như đã bỏ bản mới nhất pythonvà Ubuntu 16.04LTS dường như đã giảmaptitude .

Tôi đặt hành động sau vào bootstrap của mình trước khi thực hiện bất kỳ aptcuộc gọi nào :

- name: "FIX: Ubuntu 16.04 LTS doesn't come with certain modules, required by ansible"
  raw: apt-get install python-minimal aptitude -y
  become: true
  become_user: root
  become_method: sudo

Nếu bạn quản lý become ở nơi khác, hãy thoải mái tước nó.

Nguồn:


1

Tôi đã có thể khắc phục vấn đề tương tự bằng cách cài đặt Python trên máy đích, tức là máy mà chúng tôi muốn SSH. Tôi đã sử dụng lệnh sau:

sudo apt-get install python-minimal

1

@Miroslav, cảm ơn vì đã chỉ cho tôi đi đúng hướng. Tôi đã sử dụng user_datatrong các ec2_instancemô-đun quá và nó hoạt động như một điều trị.

I E

- name: Creating single EC2 instance 
  ec2_instance:
    region: "{{ aws_region }}"
    key_name: "{{ aws_ec2_key_pair }}"
    name: "some-cool-name"
    instance_type: t1.micro
    image_id: ami-d38a4ab1
    security_group: sg-123456
    vpc_subnet_id: sn-678901234
    network:
        assign_public_ip: no
    volumes:
      - device_name: /dev/sda1
        ebs:
          volume_type: gp2
          volume_size: 15
    user_data: |
      #!/bin/bash
      #
      apt update
      apt install -y python-simplejson              
    termination_protection: yes
    wait: yes     

1

Bạn có thể chỉ ra cho Ubuntu 18.04 rằng bạn muốn sử dụng python3 làm ưu tiên hàng đầu /usr/bin/python.

- hosts: all
  become: true
  pre_tasks:
    - raw: update-alternatives --install /usr/bin/python python /usr/bin/python3 1

0

Tôi gặp vấn đề tương tự, cho đến khi tôi nhận ra bạn cũng cần cài đặt python trên máy chủ từ xa cũng như máy cục bộ của riêng bạn. bây giờ nó hoạt động


-2

Chúng tôi chỉ chạy vào đây.

Chúng tôi triển khai Ubuntu 16.04 trên một người lang thang vì vậy nếu bạn không sử dụng vagrant thì nhận xét của tôi là vô nghĩa.

Chúng tôi đã cài đặt các plugin mơ hồ sau (trình kích hoạt, trình chỉ huy shell) và chúng tôi đã cài đặt python 2.7.6 trên máy (không phải không có plugin thioose) và sau khi có thể triển khai

Đó là thử nghiệm cuối cùng của chúng tôi, nếu không, chúng tôi sắp đưa phần cài đặt này vào lệnh shell trong tệp Vagrant

Hy vọng nó có thể giúp được ai đó


2
Nếu bạn đang sử dụng Ansible, giải pháp Ansible dưới đây là cách khắc phục chính xác. Hy vọng rằng Vagrant sẽ vô tình cài đặt nó cho bạn vì tác dụng phụ của một số plugin có vẻ như yêu cầu sự cố.
Paul Becotte

Xin lỗi nhưng làm thế nào bạn có thể chạy một Pretask ansible nếu nó không có python ??? Tôi đã thử giải pháp và nó thất bại trong thiết lập tác vụ vì vậy sự kiện trước nhiệm vụ trước. Lệnh shell vagrant trong tệp vagrant là cách tốt nhất để làm điều đó (tất nhiên đối với trường hợp mơ hồ) nhưng tôi chỉ nhận thấy rằng plugin vagrant tôi đã cài đặt trên dev của tôi thực hiện công việc. Tôi không dựa vào plugin mà dựa vào tệp vagrant, tôi chỉ chỉ ra rằng nó cũng hoạt động với plugin nhưng tệp vagrant là lựa chọn tốt hơn (cũng để tự động hóa) vì bạn không cần phải làm gì trên mỗi phá hủy / cung cấp
wadoo

1
Tôi đã sao chép khối mã chính xác như cũ và nó hoạt động chính xác như được mô tả ngay trước khi bạn đăng câu trả lời của mình. Tôi tin rằng bạn có thể đã không đặt gather_facts: nodòng vào - yêu cầu python. Khả năng khác là bạn cũng cần python trên máy chủ, nhưng tôi đoán điều đó sẽ gây ra lỗi cho bạn thậm chí sớm hơn trong quá trình.
Paul Becotte

tôi đã sao chép dán nhưng đó là thứ sáu hàng tuần tại nơi làm việc. Tôi không thể nhớ rõ nếu tôi lấy phần tập hợp. Dù sao trong một máy tính khác đã phát hiện lại vào sáng nay và tôi vừa đặt lệnh vào vagrantfile, nó là đủ cho tôi cho đến khi chúng tôi đi vào sản xuất trên máy chủ thực. Tôi sẽ kiểm tra lại với một tâm trí tươi mới (vì vậy không phải là tối thứ sáu) câu trả lời;)
wadoo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.