45

Because that's not an <, it's a <() which is completely different. This is called process substitution, it is a feature of certain shells that allows you to use the output of one process as input for another. The > and < operators redirect output to and input from files. The <() operator deals with commands (processes), not files. When you ...


38

When you do <(some_command), your shell executes the command inside the parentheses and replaces the whole thing with a file descriptor, that is connected to the command's stdout. So /dev/fd/63 is a pipe containing the output of your ls call. When you do <(ls -l) you get a Permission denied error, because the whole line is replaced with the pipe, ...


33

Process substitution results in a special file (like /dev/fd/63 in your example) that behaves like the read end of a named pipe. This file can be opened and read, but not written, not seeked. Commands that treat their arguments as pure streams work while commands that expect to seek in files they are given (or write to them) won't work. The kind of command ...


23

a | b connects STDOUT from a and STDIN from b just by using dup/dup2. Both commands are executed in parallel. a =(b) replaces the argument to a with an temporary filename. b will be executed before a as the temporary file needs to be created before it can be passed to a a <(b) replaces the argument to a with an named pipe. a and b run in parallel. This is ...


23

Here are three things you can do with process substitution that are impossible otherwise. Multiple process inputs diff <(cd /foo/bar/; ls) <(cd /foo/baz; ls) There simply is no way to do this with pipes. Preserving STDIN Say you have the following: curl -o - http://example.com/script.sh #/bin/bash read LINE echo "You said ${LINE}!" And ...


22

You seem to be grepping the list of filenames, not the files themselves. <(cat files.txt) just lists the files. Try <(cat $(cat files.txt)) to actually concatenate them and search them as a single stream, or grep -i 'foo' $(cat files.txt) to give grep all the files. However, if there are too many files on the list, you may have problems with number ...


22

Because that's how it's meant to be. <(...) in bash is the syntax for process substitution. It's copied from the same operator in ksh. <, (, ), |, &, ; are special lexical tokens in bash that are used to form special operators in different combinations. <, <(, <<, <&... each have their role. < is for redirection. <file, &...


21

Well, there are many aspects to it. File descriptors For each process, the kernel maintains a table of open files (well, it might be implemented differently, but since you are not able to see it anyways, you can just assume it's a simple table). That table contains information about which file it is/where it can be found, in which mode you opened it, at ...


21

Yes, in bash like in ksh (where the feature comes from), the processes inside the process substitution are not waited for (before running the next command in the script). for a <(...) one, that's usually fine as in: cmd1 <(cmd2) the shell will be waiting for cmd1 and cmd1 will be typically waiting for cmd2 by virtue of it reading until end-of-file ...


19

$ ps aux | tee >(head -n1) | grep syslog USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND syslog 806 0.0 0.0 34600 824 ? Sl Sep07 0:00 rsyslogd -c4 The grep and head commands start at about the same time, and both receive the same input data at their own leisure, but generally, as data becomes available. ...


19

That feature was introduced by ksh (first documented in ksh86) and was making use of the /dev/fd/n feature (added independently in some BSDs and AT&T systems earlier). In ksh and up to ksh93u, it wouldn't work unless your system had support for /dev/fd/n. zsh, bash and ksh93u+ and above can make use of temporary named pipes (named pipes added in SysIII I ...


19

/bin/sh may be bash on your system, but when invoked as sh, bash will be running in POSIX mode (as if POSIXLY_CORRECT was defined, or it was started with --posix). In this mode, process substitutions do not exist. Solutions: all: command1 >file1 command2 >file2 diff file1 file2 rm -f file1 file2 Alternative: all: bash -c "diff &...


16

Because the nc command inside <(...) will also read from stdin. Simpler example: $ nc -l 9999 >/tmp/foo & [1] 5659 $ echo text | cat <(nc -N localhost 9999) - [1]+ Done nc -l 9999 > /tmp/foo Where did the text go? Through the netcat. $ cat /tmp/foo text Your program and nc compete for the same stdin, and nc gets some ...


14

Quoting the ArchLinux wiki: Note: Because of the process substitution, you cannot run this command with sudo - you will need a root shell. You should be able to use su -c under sudo like so: $ sudo su -c 'wpa_supplicant -D nl80211,wext -i wlp4s0 -c \ <(wpa_passphrase "some ssid" "password")'


13

Borrowing from celtschk's answer, /dev/fd is a symbolic link to /proc/self/fd. And /proc is a pseudo filesystem, that presents information about processes and other system information in a hierarchical file-like structure. Files in /dev/fd correspond to files, opened by a process and has file descriptor as their names and files themselves as their targets. ...


13

You can't pass file descriptors like this over ssh. <(...) construction creates virtual files on your system and it does not have a meaning when executing on remote system. If you really want to use it, put it into the quotes, which will evaluate on the remote system, if you have bash there ssh root@remote_host "bash <( cat /root/test.sh )"


12

sh (which in most (Debian-derived) systems is linked to dash) doesn't allow process substitution. Try invoke by bash script.sh. Same calling by ./script.sh executes with sha-bang which is /bin/bash in your script.


12

You can reproduce what the shell does under the hood by doing the plumbing manually. If your system has /dev/fd/NNN entries, you can use file descriptor shuffling: you can translate main_command <(produce_arg1) <(produce_arg2) >(consume_arg3) >(consume_arg4) to { produce_arg1 | { produce_arg2 | { main_command /dev/fd5 /dev/fd6 /dev/fd3 /...


12

Those are the errors you get when trying to perform a process substitution in bash when the shell is running in POSIX mode. The bash shell does not support process substitutions in POSIX mode. bash will run in POSIX mode when either set -o posix has been used, or the shell is being invoked as sh. My hunch is that you have a script, test.sh, that you are ...


11

Process substitution <(…) creates a pipe, uses /dev/fd to give a path that's equivalent to the file descriptor where the pipe is, and passes the file name as an argument to the program. Here the program is sudo, and it passes that argument (which is just a string, as far as it's concerned) to wpa_supplicant, which treats it as a file name. The problem is ...


11

Yes, in bash like in ksh (where the feature comes from), the processes inside the process substitution are not waited for. for a <(...) one, that's usually fine as in: cmd1 <(cmd2) the shell will be waiting for cmd1 and cmd1 will be typically waiting for cmd2 by virtue of it reading until end-of-file on the pipe that is substituted, and that end-of-...


11

On Linux, /dev/fd is a symbolic link to /proc/self/fd, where /proc/self is a symlink to the process directory of the calling process. /proc/$pid/fd then contains magic links to the open filehandles. Bash uses that to make pipes that can be accessed by filename without needing to leave anything on the actual filesystem. So, you'd need to mount /proc and make ...


10

The command: ssh -F <(vagrant ssh-config) default runs the vagrant command in a separate process with its stdout connected to a pipe. The other end of the pipe is connected as file descriptor n (in your case it's 11) to a new process that runs ssh and the shell runs: ssh -F /proc/self/fd/n default Now, that only works if ssh doesn't close its file ...


10

You were really close: tr "o" "a" < <(echo "Foo") The substitution <() makes a file descriptor and just pastes the path to the shell. For comprehension just execute: <(echo blubb) You will see the error: -bash: /dev/fd/63: Permission denied That's why it just pastes /dev/fd/63 into the shell and /dev/fd/63 is not excutable, because it's a ...


9

The reason you are seeing the output of the original command is because tee outputs to stdout as well as the files specified. To discard this you can put >/dev/null at the end of the command or redirect this output to one of your process substitutions by adding an extra >, eg: command | tee >(sed -rn 's/.*foo (bar).*/1/p') > >(awk '{print $3}'...


9

That's shell dependant and not documented AFAICS. In ksh and bash, in the first case, foo will share the same stdin as bar. They will fight for the output of echo. So for instance in, $ seq 10000 | paste - <(tr 1 X)' 1 X 2 X042 3 X043 4 X044 5 X045 [...] You see evidence that paste reads every other block of text from seq'...


9

You may see foo displayed before bar, after bar, or even after the prompt, depending on timing. Add a little delay to get consistent timing: $ echo foo > >(sleep 1; cat); echo bar; sleep 2 bar foo $ bar appears immediately, then foo after one second, then the next prompt after another second. What's happening is that bash executes process ...


9

Rather than naming the results you can just name the command. param_set_1(){ input_command \ -lots \ -of \ -params } param_set_2(){ input_command \ -lots \ -of \ -other \ -params } command_outer -params <(param_set_1) <(param_set_2) You can also often refer to ...


9

The process substitution >(thing) will be replaced by a file name. This file name corresponds to a file that is connected to the standard input of the thing inside the substitution. The following would be a better example of its use: $ sort -o >(cat -n >/tmp/out) ~/.profile This would sort the file ~/.profile and send the output to cat -n which ...


9

Somewhere in the depths of zshparam(1) one may find: TMPSUFFIX A filename suffix which the shell will use for temporary files created by process substitutions (e.g., `=(list)'). Note that the value should include a leading dot `.' if intended to be interpreted as a file extension. The default is not to ...


Only top voted, non community-wiki answers of a minimum length are eligible