![]() ![]() clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6c12569a10) = 8955 How is process substitution implemented ? We can find out using the trace below (output shortened for brevity) $ strace -e clone,execve,pipe,dup2 -f bash -c 'cat <(/bin/true) <(/bin/false) <(/bin/echo)'Įxecve("/bin/bash",, 0x7ffcb96004f8 /* 50 vars */) = 0Ĭlone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6c12569a10) = 8954 As expected, wc receives that stream from two echo commands, which by itself would output two lines, each having a word, and appropriately we have 2 words, 2 lines, and 6 characters plus two newlines counted. So here we make shell create a file descriptor for all the output that happens in the parenthesis and redirect that as input to wc. So very simple example would be to make process substitution of output from two echo commands into wc: $ wc < <(echo bar echo foo) That means < redirects that file descriptor as input into a command. Now what happens if we do just process substitution? $ echo <(echo bar)Īs you can see, the shell creates temporary file descriptor /dev/fd/63 where the output goes (which according to Gilles's answer, is an anonymous pipe). Note: technically when you say < < you aren't referring to one thing, but two redirection with single < and process redirection of output from <(. So basically you can redirect output of multiple (!) commands. But notice: in the bash manpage you will see that it is denoted as <(list). So in effect this is similar to piping stdout of one command to the other, e.g. Process substitution feeds the output of a process (or processes) into Opinion: potentially because here strings make use of temporary text files, it is the possible reason why here-strings always insert a trailing newline, since text file by POSIX definition has to have lines that end in newline character. open("/tmp/sh-thd.uhpSrD", O_RDONLY) = 4 Lr-x- 1 user1 user1 64 Aug 20 13:43 3 -> /proc/10068/fdĪnd via tracing syscalls (output shortened for readability notice how temp file is opened as fd 3, data written to it, then it is re-opened with O_RDONLY flag as fd 4 and later unlinked, then dup2() onto fd 0, which is inherited by cat later ): $ strace -f -e open,read,write,dup2,unlink,execve bash -c 'cat <<< "TEST"'Įxecve("/bin/bash",, ) = 0 This can be observed via $ ls -l /proc/self/fd/ /tmp/sh-thd.761Lj9 (deleted) , which are later unlinked, thus making them occupy some memory space temporarily but not show up in the list of /tmp directory entries, and effectively exist as anonymous files, which may still be referenced via file descriptor by the shell itself, and that file descriptor being inherited by the command and later duplicated onto file descriptor 0 (stdin) via dup2() function. $ strace -e open,dup2,pipe,write -f bash -c 'cat test Replace bash with sh to see how /bin/sh performs this redirection. ![]() This can be observed via tracing system calls with strace command. In bash these are implemented via temp files, usually in the form /tmp/sh-thd., while in dash they are implemented as anonymous pipes. ![]() In effect, it's similar to running wc by itself, typing in words, then pressing Ctrl D In this example we tell wc program to wait for EOF string, then type in five words, and then type in EOF to signal that we're done giving input. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |