Помилка відповіді з / 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.