In addition to the fairly common forms of input/output redirection the shell recognizes something called process substitution. Although not documented as a form of input/output redirection, its syntax and its effects are similar.
The syntax for process substitution is:
<(list) or >(list)where each list is a command or a pipeline of commands. The effect of process substitution is to make each list act like a file. This is done by giving the list a name in the file system and then substituting that name in the command line. The list is given a name either by connecting the list to named pipe or by using a file in /dev/fd (if supported by the O/S). By doing this, the command simply sees a file name and is unaware that its reading from or writing to a command pipeline.
To substitute a command pipeline for an input file the syntax is:
command ... <(list) ...To substitute a command pipeline for an output file the syntax is:
command ... >(list) ...
At first process substitution may seem rather pointless, for example you might imagine something simple like:
uniq <(sort a)to sort a file and then find the unique lines in it, but this is more commonly (and more conveniently) written as:
sort a | uniqThe power of process substitution comes when you have multiple command pipelines that you want to connect to a single command.
For example, given the two files:
# cat a e d c b a # cat b g f e d c bTo view the lines unique to each of these two unsorted files you might do something like this:
# sort a | uniq >tmp1
# sort b | uniq >tmp2
# comm -3 tmp1 tmp2
a
f
g
# rm tmp1 tmp2
With process substitution we can do all this with one line: # comm -3 <(sort a | uniq) <(sort b | uniq)
a
f
g
Depending on your shell settings you may get an error message similar to:
syntax error near unexpected token `('
when you try to use process substitution, particularly if you try to use it within a shell script. Process substitution is not a POSIX compliant feature and so it may have to be enabled via:set +o posixBe careful not to try something like:
if [[ $use_process_substitution -eq 1 ]]; then
set +o posix
comm -3 <(sort a | uniq) <(sort b | uniq)
fi
The command set +o posix enables not only the execution of process substitution but the recognition of the syntax. So, in the example above the shell tries to parse the process substitution syntax before the "set" command is executed and therefore still sees the process substitution syntax as illegal.
Of course, note that all shells may not support process substitution, these examples will work with bash.
榪涚▼鏇挎崲涓庡懡浠ゆ浛鎹㈠緢鐩鎬技. 鍛戒護鏇挎崲鎶婁竴涓懡浠ょ殑緇撴灉璧嬪肩粰涓涓彉閲? 姣斿dir_contents=`ls -
al`鎴杧ref=$( grep word datafile). 榪涚▼鏇挎崲鎶婁竴涓繘紼嬬殑杈撳嚭鎻愪緵緇欏彟涓涓繘紼?鎹㈠彞璇濊, 瀹冩妸
涓涓懡浠ょ殑緇撴灉鍙戠粰浜嗗彟涓涓懡浠?.
鍛戒護鏇挎崲鐨勬ā鐗?/p>
鐢ㄥ渾鎷彿鎵╄搗鏉ョ殑鍛戒護
>(command)
<(command)
鍚姩榪涚▼鏇挎崲. 瀹冧嬌鐢?dev/fd/<n>鏂囦歡灝嗗渾鎷彿涓殑榪涚▼澶勭悊緇撴灉鍙戦佺粰鍙︿竴涓繘紼? [1] (璇?/p>
鑰呮敞: 瀹為檯涓婄幇浠g殑UNIX綾繪搷浣滅郴緇熸彁渚涚殑/dev/fd/n鏂囦歡鏄笌鏂囦歡鎻忚堪絎︾浉鍏崇殑, 鏁存暟n鎸囩殑灝?/p>
鏄繘紼嬭繍琛屾椂瀵瑰簲鏁板瓧鐨勬枃浠舵弿榪扮)
鍦?<"鎴?>"涓庡渾鎷彿涔嬮棿鏄病鏈夌┖鏍肩殑. 濡傛灉鍔犱簡絀烘牸, 浼氫駭鐢熼敊璇?
bash$ echo >(true)
/dev/fd/63
bash$ echo <(true)
/dev/fd/63
Bash鍦ㄤ袱涓枃浠舵弿榪扮涔嬮棿鍒涘緩浜嗕竴涓閬? --fIn鍜宖Out--. true鍛戒護鐨剆tdin琚繛鎺ュ埌fOut
(dup2(fOut, 0)), 鐒跺悗Bash鎶?dev/fd/fIn浣滀負鍙傛暟浼犵粰echo. 濡傛灉緋葷粺緙轟箯/dev/fd/<n>鏂囦歡, Bash浼?/p>
浣跨敤涓存椂鏂囦歡. (鎰熻阿, S.C.)
榪涚▼鏇挎崲鍙互姣旇緝涓や釜涓嶅悓鍛戒護鐨勮緭鍑? 鐢氳嚦鑳藉姣旇緝鍚屼竴涓懡浠や笉鍚岄夐」鎯呭喌涓嬬殑杈撳嚭.
bash$ comm <(ls -l) <(ls -al)
total 12
-rw-rw-r-- 1 bozo bozo 78 Mar 10 12:58 File0
-rw-rw-r-- 1 bozo bozo 42 Mar 10 12:58 File2
-rw-rw-r-- 1 bozo bozo 103 Mar 10 12:58 t2.sh
total 20
drwxrwxrwx 2 bozo bozo 4096 Mar 10 18:10 .
drwx------ 72 bozo bozo 4096 Mar 10 17:58 ..
-rw-rw-r-- 1 bozo bozo 78 Mar 10 12:58 File0
-rw-rw-r-- 1 bozo bozo 42 Mar 10 12:58 File2
-rw-rw-r-- 1 bozo bozo 103 Mar 10 12:58 t2.sh
浣跨敤榪涚▼鏇挎崲鏉ユ瘮杈冧袱涓笉鍚岀洰褰曠殑鍐呭(鍙互鏌ョ湅鍝簺鏂囦歡鍚嶇浉鍚? 鍝簺鏂囦歡鍚嶄笉鍚?:
1 diff <(ls $first_directory) <(ls $second_directory)
涓浜涜繘紼嬫浛鎹㈢殑鍏朵粬鐢ㄦ硶涓庢妧宸?
1 cat <(ls -l)
2 # 絳変環浜?ls -l | cat
3
4 sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin)
5 # 鍒楀嚭緋葷粺3涓富瑕?bin'鐩綍涓殑鎵鏈夋枃浠? 騫朵笖鎸夋枃浠跺悕榪涜鎺掑簭.
6 # 娉ㄦ剰鏄?涓?鏌ヤ竴涓? 涓婇潰灝?涓渾鎷彿)鏄庢樉涓嶅悓鐨勫懡浠よ緭鍑轟紶閫掔粰'sort'.
7
8
9 diff <(command1) <(command2) # 緇欏嚭涓や釜鍛戒護杈撳嚭鐨勪笉鍚屼箣澶?
10
11 tar cf >(bzip2 -c > file.tar.bz2) $directory_name
12 # 璋冪敤"tar cf /dev/fd/?? $directory_name", 鍜?bzip2 -c > file.tar.bz2".
13 #
14 # 鍥犱負/dev/fd/<n>鐨勭郴緇熷睘鎬?
15 # 鎵浠ヤ袱涓懡浠や箣闂寸殑綆¢亾涓嶅繀琚懡鍚?
16 #
17 # 榪欑鏁堟灉鍙互琚ā鎷熷嚭鏉?
18 #
19 bzip2 -c < pipe > file.tar.bz2&
20 tar cf pipe $directory_name
21 rm pipe
22 # 鎴?/p>
23 exec 3>&1
24 tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-
25 exec 3>&-
26
27
28 # 鎰熻阿, Stephane Chazelas
涓涓鑰呯粰鎴戝彂浜嗕竴涓湁瓚g殑渚嬪瓙, 鏄叧浜庤繘紼嬫浛鎹㈢殑, 濡備笅.
1 # 鎽樿嚜SuSE鍙戣鐗堜腑鐨勪唬鐮佺墖鏂?
2
3 while read des what mask iface; do
4 # 榪欓噷鐪佺暐浜嗕竴浜涘懡浠?..
5 done < <(route -n)
6
7
8 # 涓轟簡嫻嬭瘯瀹? 鎴戜滑璁╁畠鍋氱偣浜?
9 while read des what mask iface; do
10 echo $des $what $mask $iface
11 done < <(route -n)
12
13 # 杈撳嚭:
14 # Kernel IP routing table
15 # Destination Gateway Genmask Flags Metric Ref Use Iface
16 # 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
17
18
19
20 # 灝卞儚Stephane Chazelas鎵緇欏嚭鐨勯偅鏍? 涓涓洿瀹規槗鐞嗚В鐨勭瓑浠蜂唬鐮佹槸:
21 route -n |
22 while read des what mask iface; do # 綆¢亾鐨勮緭鍑鴻璧嬪肩粰浜嗗彉閲?
23 echo $des $what $mask $iface
24 done # 榪欏皢浜х敓鍑轟笌涓婅竟鐩稿悓鐨勮緭鍑?
25 # 鐒惰? Ulrich Gayer鎸囧嚭 . . .
26 #+ 榪欎釜綆鍗曠殑絳変環鐗堟湰鍦╳hile寰幆涓嬌鐢ㄤ簡涓涓瓙shell,
27 #+ 鍥犳褰撶閬撶粨鏉熷悗, 鍙橀噺灝辨秷澶變簡.
28
29
30
31 # 鏇磋繘涓姝? Filip Moritz瑙i噴浜嗕笂闈袱涓緥瀛愪箣闂村瓨鍦ㄤ竴涓粏寰殑涓嶅悓涔嬪,
32 #+ 濡備笅鎵紺?
33
34 (
35 route -n | while read x; do ((y++)); done
36 echo $y # $y 浠嶇劧娌℃湁琚0鏄庢垨璁劇疆
37
38 while read x; do ((y++)); done < <(route -n)
39 echo $y # $y 鐨勫間負route -n鐨勮緭鍑鴻鏁?
40 )
41
42 # 涓鑸潵璇? (璇戣呮敞: 鍘熶功浣滆呭湪榪欓噷騫舵湭鍔犳敞閲婄鍙?#", 搴旇鏄瑪璇?
43 (
44 : | x=x
45 # 鐪嬩笂鍘繪槸鍚姩浜嗕竴涓瓙shell
46 : | ( x=x )
47 # 浣?/p>
48 x=x < <(:)
49 # 鍏跺疄涓嶆槸
50 )
51
52 # 褰撲綘瑕佽В鏋恈sv鎴栫被浼間笢瑗跨殑鏃朵警, 榪欓潪甯告湁鐢?
53 # 浜嬪疄涓? 榪欏氨鏄疭uSE鐨勮繖涓唬鐮佺墖鏂墍瑕佸疄鐜扮殑鍔熻兘.
娉ㄦ剰浜嬮」
[1] 榪欎笌鍛藉悕綆¢亾(涓存椂鏂囦歡)鍏鋒湁鐩稿悓鐨勪綔鐢? 騫朵笖, 浜嬪疄涓? 鍛藉悕綆¢亾涔熻鍚屾椂浣跨敤鍦ㄨ繘紼?/p>
鏇挎崲涓?



