Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shell module: < with ansible

I want to run a command:

- name: install pip
  shell: "python <(curl https://bootstrap.pypa.io/get-pip.py)"

But achieve an error

failed: [default] => {"changed": true, "cmd": "python <(curl https://bootstrap.pypa.io/get-pip.py)", "delta": "0:00:00.002073", "end": "2014-12-03 15:52:01.780837", "rc": 2, "start": "2014-12-03 15:52:01.778764", "warnings": []}
stderr: /bin/sh: 1: Syntax error: "(" unexpected

I tried to change it to something like:

python <$(curl https://bootstrap.pypa.io/get-pip.py)

but it doesn't work. Any thoughts?

NB: this question about using < operator in shell module and I know that better to use apt for install something

like image 395
kharandziuk Avatar asked Dec 03 '14 15:12

kharandziuk


People also ask

How do you use the shell command in Ansible?

Ansible's shell module executes shell commands on remote hosts. By default, the shell module uses the /bin/sh shell to execute commands, but it's possible to use other shells such as /bin/bash by passing the executable argument.

What is the difference between command and shell module in Ansible?

Both modules execute commands on target nodes but in a sensible different way. The command modules execute commands on the target machine without using the target shell, it simply executes the command. The target shell is for example the popular bash , zsh , or sh .

What is the use of shell module?

The shell module executes commands directly on the shell of target hosts. By default, the shell module uses the /bin/sh shell to run commands, although you can configure it to use other shells. With the command module, the executed commands are not processed through the shell.


2 Answers

Use command module if you actually do not need shell.

Also you will be better off using get_url module for downloading the file instead of relying on curl being installed on remote server. Recent versions of Ansible will display a warning when you try to use curl instead of get_url module also:

"warnings": ["Consider using get_url module rather than running curl"]

Here is how I would do this:

- name: Download pip installer
  get_url:
    url=https://bootstrap.pypa.io/get-pip.py
    dest=/tmp/get-pip.py
    mode=0440

- name: Install pip
  command: /usr/bin/python /tmp/get-pip.py

For extra options to get_url module visit: http://docs.ansible.com/get_url_module.html

like image 50
Michal Gasek Avatar answered Sep 28 '22 04:09

Michal Gasek


EDIT: though this answers this the question I think mgsk's answer is a better answer since I agree that it's not the right way to go about it with Ansible.

This should fix your issue:

- name: install pip
  shell: "python <(curl https://bootstrap.pypa.io/get-pip.py)" executable=/bin/bash

If you are wondering the difference between these two commands:

python <(curl https://bootstrap.pypa.io/get-pip.py)
python <$(curl https://bootstrap.pypa.io/get-pip.py)

The first one uses process substitution which is a bash feature which is why you cannot use it with /bin/sh as your shell. What it's doing is taking the output of the curl command (which is a python script), writing it to a temporary file and using that file as an argument to python which takes a python script as its first argument.

The second one is an ambiguous redirect because the python script that is generated from the curl is not a file

like image 28
jarv Avatar answered Sep 28 '22 04:09

jarv