I'm trying to install RVM. There is a magical command line:
bash < <(curl -s https://rvm.io/install/rvm)
I know what bash and curl are. I know the first <
is the I/O redirection. But what does <()
syntax mean?
What's the difference between this command and
bash < `curl -s https://rvm.io/install/rvm`
?(the latter command doesn't work)
This is bash's process substitution.
The expression <(list)
gets replaced by a file name, either a named FIFO or an entry under /dev/fd
. So to actually redirect input from it, you have to use < <(list)
.
[edit; forgot to answer your second question]
The backticks are called "command substitution". Unlike process substitution, it is part of the POSIX shell specification (i.e., not a bash extension). The shell runs the command in the backticks and substitutes its output on the command line. So this would make sense:
cat < `echo /etc/termcap`
But this would not:
cat < `cat /etc/termcap`
The latter is similar to your example; it tries to use the (complex) output of a command as a file name from which to redirect standard input.
The others have already answered your question very nicely. I'll just add an example to build on them... 99% of the time when I personally use <()
, it's to diff the output of two different commands in one shot. For instance,
diff <( some_command ) <( some_other_command )
The syntax for io redirection is
process < file
Hence you need whatever appears after the io redirect to be a filename.
The backtick expansion literally puts the results of the command into the command line. Thus,
`curl -s https://rvm.io/install/rvm`
expands to something like #!/usr/bin/env bash ...
and the shell would be confused because it would see
bash < #...
instead of a filename.
the <()
operator is process substitution, which spawns a new process to run the command within the (..). A new file or pipe is created that will capture the result. The fact that the arrow is pointing left <()
instead of >()
means that the output from the inner process will be written to the file, which can be read by the process.
In your case, bash < <(...)
will be seen as something like bash < /dev/fd/100
If you actually want to see what is going on, run
echo <(curl -s https://rvm.io/install/rvm)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With