Помилка відповіді з / bin / sh: 1: / usr / bin / python: не знайдено


187

Я стикаюся з помилкою, якої я ніколи не бачив. Ось команда та помилка:

$ 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

Ось файл create_api.yml:

---

- hosts: api
  remote_user: root
  roles:
    - api

А ось файл хостів:

[api]
104.55.47.224

Я можу видалити розділ ролей, і він не зробить його першим ЗАВДАННЯм, він замість цього зробить лише перехід на рядок /bin/sh: 1: /usr/bin/python: not found. Що тут може бути?


ПРИМІТКА. Якщо хтось вводить пінг-адресу IP і не отримує відповіді, ви повинні знати, що я змінив IP-адресу з моменту вставки коду.

EDIT python був встановлений локально, проблема полягала в тому, що він не був встановлений на віддаленій машині, на якій працює Ubuntu 15.04

Відповіді:


171

Я натрапив на цю помилку запуску ansible на сервері Ubuntu 15.10 , оскільки він постачається з Python 3.4.3, а ansible вимагає Python 2 .

Ось як provision.ymlвиглядає зараз:

- 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
  • Не забувайте варіант -y (відповідає так на всі запитання) з опцією apt-get (або сирий модуль застрягне мовчки)

  • gather_facts: no лінія також є критичною (тому що ми не можемо зібрати факти без пітона)


12
Тож наступні ролі не можуть використовувати факти ... чи є спосіб знову зібрати факти? ага, stackoverflow.com/questions/31054453/…
— stephen

16
Зауважте, що рядок "збирати_факти: немає" також є критичним.
— rcreswick

6
@ surfer190 чудова знахідка! Я також виявив, що додавання action: setupяк фінальний pre_task також спрацювало чудово :)
— mrooney

1
@ surfer190 дивіться мою відповідь тут, якщо ви використовуєте EC2 з ansible, ви можете використовувати CloudInit для установки python2, щоб ви могли використовувати факти збирання, як зазвичай.
— Мирослав

1
Якщо хтось теж цікавиться, не потрібно запускати rawзавдання встановити Python 2 pre_tasks; регулярно tasksтеж працює добре. Але введення цього pre_tasksзавдання з завданням викликати setupмодуль Ansible також забезпечить доступність фактів для будь-яких ролей, призначених хосту.
— Кенні Евітт

125

В Ansible 2.2 представлений технічний перегляд підтримки Python 3. Щоб скористатися цим (щоб вам не довелося встановлювати Python 2 на Ubuntu 16.04), просто встановіть для ansible_python_interpreterпараметра налаштування значення /usr/bin/python3. Це можна зробити на основі хоста у вашому інвентарному файлі:

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

Я спробував додати / usr / bin / python до цієї змінної, але це не спрацювало. Додавання python3 замість цього спрацювало, і ця проблема виправлена
— Deep LF

98

Рішення 1:

Якщо ви використовуєте Ansible >2.2.0, ви можете встановити параметр ansible_python_interpreterконфігурації /usr/bin/python3:

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

або у вашому інвентарному файлі:

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

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

Рішення 2:

Якщо ви користуєтесь, Ansible <2.2.0ви можете додати їх pre_tasksу свою книгу програвання:

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

ОНОВЛЕННЯ З цим ansible 2.8.x, вам не потрібно турбуватися про це, він працює з коробки для python> 3.5 як для контролера, так і для цільової машини


Якщо ви запускаєте свої ігрові книги за допомогою тегів, обов’язково додайте теги: завжди до завдання налаштування - інакше ansible не збиратиме факти при використанні тегів.
— Іонут Баєску

16
У мене є, ansible 2.3.0.0і це не виходить з коробки. Та ж помилка, яку опублікувала ОП.
— Кодер

Якщо це явно не зрозуміло, ви повинні додати це до файлу інвентаря хоста, а не до включеного vars, тобто він знаходиться в тому ж інвентарному файлі, що і адреса / ім'я хоста.
— Шон Механ

32

Ви можете використовувати необроблений модуль для установки Python на віддалені хости:

- raw: sudo apt-get install python-simplejson

11
Щоб переконатися, що це викликається перед завданнями у вашій ролі та перед будь-якими залежностями у вашому мета-файлі, додайте це так у свою програму: pre_tasks: - raw: sudo apt-get install python-simplejson
— Laurens Rietveld

5
Зауважте, що в ігровій книзі ви також повинні відключити збирати_факти, інакше це не вдасться перед запуском необробленої команди. (збирати_факти: ні)
— rcreswick

@rcreswick Це була моя проблема, і ваше рішення працювало на мене. Дуже дякую. Я помістив рядок "збирати_факти: ні" у свій головний файл .yml (setup-ansible.yml) і виконав програму з цією командою: "ansible-playbook -i hosts setup-ansible.yml --flush-cache -vvvvvvv -kK ". Я використовував параметри "-kK" з ansible-playbook, оскільки для встановлення ubuntu за замовчуванням потрібен пароль, щоб зробити "sudo".
— Алі Юсефі Сабзевар

чому ви встановлюєте simplejson, а не pytghon, але говорите про встановлення python?
— Хеннінг

@Henning python-simplejsonнаписаний на Python і тому вимагає Python. simplejson також є вимогою до більшості базових модулів Ansible. Встановлюючи python-simplejsonчерез apt-get/ yumви також встановлюєте Python і, таким чином, покриваєте всі основні залежності від Ansible ...
— udondan

18

Щоб узагальнити відповіді всіх інших, ось комбіновані налаштування, які працювали для мене:

 - 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

Я особисто знайшов 3 можливі рішення цієї проблеми, які добре працюють у різних ситуаціях:

Варіант 1 - встановлення ansible_python_interpreter: /usr/bin/python3для хостів, які python3встановлені за замовчуванням

Я думаю, що це найкращий метод вирішення проблеми, якщо у вас є спосіб згрупувати своїх хостів за тим, чи python3встановлені вони за замовчуванням. Наскільки мені відомо, python3він доступний у всіх версіях Ubuntu 16.04 та новіших версій.

  • Якщо всі ваші хости напевно є python3, ви можете додати змінну до своєї group_vars/all.yml(або еквівалентної):
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
  • Якщо у деяких ваших хостів немає python3і у вас є спосіб позначити їх під час використання динамічного інвентаря (наприклад, тегів AWS ec2.py), ви можете застосувати цю змінну до певних хостів, таких як ця:
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3
  • Якщо ви використовуєте статичний інвентар та вмієте групувати хости на основі того, чи є вони python3, ви можете зробити щось подібне:
# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

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

Цей варіант мені найбільше подобається, оскільки він не потребує змін на віддаленому хості та лише незначні зміни змінних, на відміну від варіантів 2 та 3, які потребують доповнень до кожної книги.

Варіант 2 - Встановіть Python 2 за допомогою raw

Цей параметр вимагає розміщення відтворення у верхній частині кожної ігрової книги, gather_facts: falseяка використовується rawдля встановлення 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: trueпотрібен, якщо ви плануєте запустити програвання на хостах, які не apt-getвстановлені (наприклад, що-небудь на основі RHEL), інакше вони помиляться під час першого відтворення.

Це рішення працює, але є найнижчим у моєму списку з кількох причин:

  1. Потрібно переглядати верхню частину кожної книги (на відміну від варіанта 1)
  2. Припускає apt, що в системі та ігнорує помилки (на відміну від варіанта 3)
  3. apt-get команди повільні (на відміну від варіанта 3)

Варіант 3 - /usr/bin/python -> /usr/bin/python3Використання Symlinkraw

Я не бачив цього рішення, запропонованого ким-небудь ще. Це не ідеально, але я думаю, що багато в чому перевершує варіант 2. Моя пропозиція - використовувати rawдля запуску команди оболонки для символьного посилання, /usr/bin/python -> /usr/bin/python3якщо python3в системі немає, а python ні:

- 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

Це рішення схоже з варіантом 2 тим, що нам потрібно поставити його у верхній частині кожної ігрової книги, але я думаю, що воно перевершує декілька способів:

  • Символьне посилання створюється лише в конкретному випадку, який python3є, а pythonне - він не перекриє Python 2, якщо він уже встановлений
  • Не припускає apt, що встановлено
  • Може працювати з усіма хостами без особливих помилок
  • Супер швидкий порівняно з чим-небудь із apt-get

Очевидно, якщо вам потрібен Python 2, встановлений на /usr/bin/python, це рішення не працює, а варіант 2 кращий.

Висновок

  • Я пропоную використовувати варіант 1 у всіх випадках, якщо можете.
  • Я пропоную скористатися варіантом 3, якщо ваш інвентар дійсно великий / складний, і ви не можете легко згрупувати хости python3, що зробить варіант 1 набагато складнішим і схильним до помилок.
  • Я пропоную лише варіант 2 над варіантом 3, якщо вам потрібен Python 2, встановлений на /usr/bin/python.

Джерела


13

Для запуску Ansible вам потрібен python 2.7. У Ubuntu 16.04 ви можете встановити його за допомогою цієї команди:

sudo apt-get install python-minimal

Після цього я міг бігати

ansible-playbook -i inventories/staging playbook.yml

Успішно виконайте ansible

Будь ласка, перевірте детальніше в розділі Використання ansible на Ubuntu 16.04


12

Що я використовував для роботи над ubuntu 15.10 над свіжою крапелькою Digital Ocean:

# 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

Для ubuntu 16.04 на свіжому SSH-диску SSH мені довелося апт-отримати оновлення до того, як пакети python2 були доступні.


8

Я з’ясував, що насправді в одній програмі можливо встановити кілька відтворень, тому в моєму налаштуванні тепер грає "забезпечення залежностей", яка працює на всіх хостах, та інші відтворення для конкретних хостів. Так що більшеpre_tasks .

Наприклад:

- 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

Як говорили інші, це пов'язано з відсутністю python2. Інші відповіді тут забезпечують обхідний шлях з pre_tasksі gather_facts: no, тим НЕ менш , якщо ви на EC2 і ви розкручуєте екземпляр з анзіблем ви можете використовувати user_dataопцію:

- 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

Тоді люди зазвичай чекають, коли ssh стане доступним так:

  - 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

Однак я виявив, що це не завжди досить довго, оскільки CloudInit виконується досить пізно в процесі завантаження, тому python2 все ще не може бути встановлений відразу після появи ssh. Тому я додав паузу у випадку, якщо екземпляр щойно створений:

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

Це зробить роботу ідеально, і як перевага ви не перевіряєте наявність python2 на кожному запуску, і вам не доведеться робити жодних обхідних шляхів, щоб зібрати факти пізніше.

Я впевнений, що інші постачальники послуг хмари надають подібну функцію CloudInit, тому адаптуйтеся до вашого випадку використання.


3

ТЕ, що використовують Packer, може виявити, що рішення нижче є корисним

припустимо, що ви використовуєте відповідальний провайдер пакера, ваша конфігурація може виглядати нижче

ви можете встановити python спочатку за допомогою провідника оболонки, а потім налаштуйте опцію ansible_python_intepreter, як показано нижче

"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

За замовчуванням Ansible вимагає Python 2 , однак Ansible 2.2+ може також працювати з Python 3 .

Тож установіть Python 2 за допомогою rawмодуля , наприклад

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

або встановити ansible_python_interpreterзмінну у інвентарному файлі, наприклад:

[local]
localhost ansible_python_interpreter="env python3"

Для Docker ви можете додати такий рядок:

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

або запустити його як:

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

1

Відповідно до цього Gist, ви можете встановити Python2 на Ubuntu 16.04 наступним чином:

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

Багато відповідей .. Дякую за публікацію, як я почав працювати і з цієї сторінки!

Я трохи копав, і це було міцно з Ubuntu 14.04LTS, Ubuntu 15.04LTS, здавалося, випав останні python, а Ubuntu 16.04LTS, схоже, впав aptitude.

Перед тим, як робити будь-які aptдзвінки, я ставлю наступні дії до свого завантажувального пристрою :

- 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

Якщо ви керуєте в becomeіншому місці, сміливо зніміть його.

Джерела:


1

Мені вдалося виправити ту саму проблему, встановивши Python на цільовій машині, тобто машині, до якої ми хочемо SSH. Я використав таку команду:

sudo apt-get install python-minimal

1

@Miroslav, дякую за те, що я вказав мені в правильному напрямку. Я використовував user_dataуec2_instance модулі занадто , і він працює як лікувати.

Тобто

- 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

Ви можете вказати Ubuntu 18.04, що ви хочете використовувати python3 як перший пріоритет /usr/bin/python.

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

0

У мене була така ж проблема, поки я не зрозумів, що вам також потрібно встановити python на віддалений хост, а також свою власну локальну машину. тепер це працює!


-2

Ми просто стикаємося з цим.

Ми розгортаємо ubuntu 16.04 на бродягу, тому якщо ви не використовуєте бродягу, мій коментар є безглуздим.

Ми встановили наступні бродячі плагіни (тригер, оболонка-командир) і ми отримуємо python 2.7.6, встановлений на машині (які не були без тіозних плагінів), і після того, як ansible може розгорнути

Це був наш останній тест, інакше ми збиралися включити цю установку до команди оболонки у файлі Vagrant

Сподіваюся, це може комусь допомогти


2
Якщо ви використовуєте Ansible, рішення Ansible нижче - це правильне виправлення. Сподівання на те, що Vagrant випадково встановить його для вас як побічний ефект деяких плагінів, схоже, вимагає неприємностей.
— Пол Бекотт

Вибачте, але як ви можете запустити антителеву підказку, якщо вона не має python ??? Я спробував рішення, і це не вдалося при встановленні завдання, так що подія перед попереднім завданням. Команда блукаючої оболонки у файлі бродяжника - це найкращий спосіб зробити це (для випадку бродячого, звичайно), але я просто зауважую, що плагін бродяги, який я встановив на своєму розробнику, виконує цю роботу. Я не покладаюся на плагін, а на файл бродяги, я просто зазначив, що він працює і з плагіном, але файл бродяги є кращим вибором (також для автоматизації), оскільки вам вручну нічого не потрібно робити на кожному знищити / забезпечити
— wadoo

1
Я скопіював цей код коду саме таким, який він був, і він працював точно так, як описано прямо перед тим, як ви опублікували свою відповідь. Я вважаю, що ви, ймовірно, не ввели gather_facts: noрядок - для цього потрібен python. Інша можливість полягає в тому, що вам також потрібен python на хост-машині, але я б припустив, що це призвело б до помилок ще раніше.
— Пол Бекотт

Я теж скопіював пасту, але це було п’ятнице нігтя на роботі. Я не можу чесно пам’ятати, якби я взяв участь у збірці_факту. У будь-якому разі в іншому комп’ютері сьогодні знову вранці, і я щойно ставлю команду в vagrantfile, мені достатньо, поки ми не перейдемо до виробництва на реальному сервері. Я знову
— перевірю
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.