Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

A newbie question.. I was installing RVM (a tool to manage Ruby versions). The command for it is:

bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

I know a little bit that the < is a command redirection operator (correct?).

Then, why is the second < needed (what does it do)?

share|improve this question
    
This really isn't a newbie question; it's quite advanced. Good for you for being curious. –  Stefano Palazzo Nov 25 '10 at 9:45
add comment

2 Answers 2

up vote 5 down vote accepted

It turns a string into the file descriptor for the output of the bash script that it represents. This might be confusing, here's an example

if you type echo <(ls) it will open a new file descriptor, the name of which is substituted. So the command might turn into say echo /dev/fd/63.

A program that expects a file can now read the output of the command without having to accept stdin.

$ my_program ls
Error: 'ls': No such file or directory.
$ my_program <(ls)
my_program was called with the argument /dev/fd/63
bin dev etc ...

Many Linux program will, if not provided with a source of input, wait for standard input. Because standard output can be piped to standard input with the "| " operator, you can then use say ls | grep hello. This only works because grep would've waited for input anway, if it'd expected a file name to open and read to get its data, the pipe operator doesn't work. This is why you need <(...).

I hope this is intelligible. :-)

Together with the < operator to redirect the output of a file to a programs reading of stdin, this makes for the following meaning:

Bash: read the output from this file, which is created from the output of this command.

Clarifications:

  • standard input: a "file" (not really, but in linux everything acts like a file) that, when read, magically contains what you've typed
  • standard output: a "file" that, when written to, will be printed to the virtual terminal
  • operator (i.e. < or <()): Same as in regular maths, expressions of operators and operands will be evaluated and substituted. 3+2*3 turns into 5*3 turns into 15. It's the same in the bash language.

A nice example to emphasize Roger's point is this expression:

if [ -f my_condition ] then something fi

Here the contents of the brackets will be evaluated as a conditional statement, i.e. if my_condition is true, then do something. But: [ is actually just an alias of the program test, which, when called with the parameter -f, will check if a file exists.

share|improve this answer
    
the way it is posted in the question, it will feed the output from the curl command into the input of bash, whereas bash | curl http://... will do it the other way around. Did you mean curl http://... | bash ? That would work in this case. –  koushik Nov 25 '10 at 9:31
    
That's what I meant of course, well spotted. I'm still a bit tired. :-) –  Stefano Palazzo Nov 25 '10 at 9:36
    
Thanks! A lot to chew on, i will definitely read more. Btw, is there a "name" for this <() operator? –  Zabba Nov 25 '10 at 10:26
1  
Oh, got it: 3.5.6 Process Substitution –  Zabba Nov 25 '10 at 10:28
add comment

To clarify Stefano's point, the second < isn't just a <, it's actually <()

You may already be familiar with a similar construct, $() which produces a string that is the result of the command within it. So:

$ which bash # echo the path to bash
/bin/bash
$ ldd $(which bash) # return which libraries bash is linked to
...

After the string substitution this is equivalent to

ldd /bin/bash

As Stefano says, <() does a very similar thing but instead returns a file descriptor.

You can find the bash documentation in man bash. As it's a huge man page, you can search (press /) for <\( (you need to escape the open bracket - searching for <( won't work).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.