Tricky shell syntax error

I’m trying to run a task that invokes bash as part of the task. The command works directly from the user’s command line on the box but fails when run via Ansible:

Here’s the task that’s running:

  • name: Install User RVM via RVM::FW
    when: rvm_fw == True and rvm_version.rc != 0
    shell: \bash < <( curl {{rvm_fw_url}}/releases/rvm-install-latest )
    register: rvm_install
    failed_when: rvm_install.rc != 0

And the resulting output:

TASK: [ruby | Install User RVM via RVM::FW] ***********************************
failed: [33.33.33.10] => {“changed”: true, “cmd”: "\bash < <( curl http://rvm-fw.herokuapp.com/releases/rvm-install-latest ) ", “delta”: “0:00:00.002708”, “end”: “2013-11-29 18:23:45.768494”, “failed”: true, “failed_when_result”: true, “item”: “”, “rc”: 2, “start”: “2013-11-29 18:23:45.765786”, “stdout_lines”: }
stderr: /bin/sh: -c: line 0: syntax error near unexpected token <' /bin/sh: -c: line 0: \bash < <( curl http://rvm-fw.herokuapp.com/releases/rvm-install-latest ) ’

Any ideas on how to tweak this line so that Ansible’s shell module will pass it through properly?

Ansible version is 1.4.0 currently.

Thanks for everyone’s help as always,

Steven

Sorry, the shell action line should read:

shell: bash < <( curl {{rvm_fw_url}}/releases/rvm-install-latest )

I tried to escape it as a debug measure with no success.

Thanks!

Hi Steven,

Any chance this can be solved by changing 'bash < <( curl
{{rvm_fw_url}}/releases/rvm-install-latest )' to 'curl
{{rvm_fw_url}}/releases/rvm-install-latest | bash' ?
The shell module is a bit tricky sometimes :slight_smile:

M

Michel,

It’s definitely not the way old school RVM instructions said it had to be done, but it seems to work on this particular instance just fine!

Thanks!

Try:

shell: “bash < <( curl {{rvm_fw_url}}/releases/rvm-install-latest )”

Cheers,
Lars

Lars,

Thanks. I actually tried wrapping it in quotes before posting with no change. Sorry I forgot to mention that.

-Steven

You should probably download a local copy of that install script, review it personally, and save it to a server or in a location you trust. Then deploy that script with the script module, which is native in Ansible.

http://ansibleworks.com/docs/modules.html#script

Package systems like EPEL are at least generally signed, but it’s ridiculously easy to see a webserver compromised, for instance, in taking advantage of a bug in wordpress.

Michael,

Thanks! This is incredibly wise advice. The script itself is actually from the first year of RVM’s installation process itself. The new installation script they have is considerably too complicated for me to follow and so I’ve stuck to maintaining the original one on my RVM::FW project.

I actually created and maintain the RVM::FW project (including this script). Rather than duplicating this script and copying it out myself, since others use this on internal production networks already, is there a tutorial or suggestion on how to learn about properly signing this script or securing it more soundly?

I appreciate your help as always. Ansible has already made learning it an extremely wise choice if only to help me improve some of my basic sysadmin habits.

Thanks!

for information on why

shell: bash < <( curl {{rvm_fw_url}}/releases/rvm-install-latest )

did not work when you tried with ansible.

the notation “<(commands)” is called “process substitution” and is a bash extension that does not exist in the bourne shell /bin/sh. It exists in other shells too.

by default, ansible systematically executes commands inside a /bin/sh shell so the <(command) breaks with the message you got.

if you really want to execute it after Michael’s warning, it should work with :

shell: bash < <( curl {{rvm_fw_url}}/releases/rvm-install-latest ) executable=/usr/bin/bash