874 lines
14 KiB
HTML
874 lines
14 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||
<HTML
|
||
><HEAD
|
||
><TITLE
|
||
>Process Substitution</TITLE
|
||
><META
|
||
NAME="GENERATOR"
|
||
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
|
||
REL="HOME"
|
||
TITLE="Advanced Bash-Scripting Guide"
|
||
HREF="index.html"><LINK
|
||
REL="UP"
|
||
TITLE="Advanced Topics"
|
||
HREF="part5.html"><LINK
|
||
REL="PREVIOUS"
|
||
TITLE="Restricted Shells"
|
||
HREF="restricted-sh.html"><LINK
|
||
REL="NEXT"
|
||
TITLE="Functions"
|
||
HREF="functions.html"></HEAD
|
||
><BODY
|
||
CLASS="CHAPTER"
|
||
BGCOLOR="#FFFFFF"
|
||
TEXT="#000000"
|
||
LINK="#0000FF"
|
||
VLINK="#840084"
|
||
ALINK="#0000FF"
|
||
><DIV
|
||
CLASS="NAVHEADER"
|
||
><TABLE
|
||
SUMMARY="Header navigation table"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
CELLPADDING="0"
|
||
CELLSPACING="0"
|
||
><TR
|
||
><TH
|
||
COLSPAN="3"
|
||
ALIGN="center"
|
||
>Advanced Bash-Scripting Guide: </TH
|
||
></TR
|
||
><TR
|
||
><TD
|
||
WIDTH="10%"
|
||
ALIGN="left"
|
||
VALIGN="bottom"
|
||
><A
|
||
HREF="restricted-sh.html"
|
||
ACCESSKEY="P"
|
||
>Prev</A
|
||
></TD
|
||
><TD
|
||
WIDTH="80%"
|
||
ALIGN="center"
|
||
VALIGN="bottom"
|
||
></TD
|
||
><TD
|
||
WIDTH="10%"
|
||
ALIGN="right"
|
||
VALIGN="bottom"
|
||
><A
|
||
HREF="functions.html"
|
||
ACCESSKEY="N"
|
||
>Next</A
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
><HR
|
||
ALIGN="LEFT"
|
||
WIDTH="100%"></DIV
|
||
><DIV
|
||
CLASS="CHAPTER"
|
||
><H1
|
||
><A
|
||
NAME="PROCESS-SUB"
|
||
></A
|
||
>Chapter 23. Process Substitution</H1
|
||
><P
|
||
><A
|
||
NAME="PROCESSSUBREF"
|
||
></A
|
||
><A
|
||
HREF="special-chars.html#PIPEREF"
|
||
>Piping</A
|
||
> the <TT
|
||
CLASS="FILENAME"
|
||
>stdout</TT
|
||
>
|
||
of a command into the <TT
|
||
CLASS="FILENAME"
|
||
>stdin</TT
|
||
> of another
|
||
is a powerful technique. But, what if you need to pipe the
|
||
<TT
|
||
CLASS="FILENAME"
|
||
>stdout</TT
|
||
> of <EM
|
||
>multiple</EM
|
||
>
|
||
commands? This is where <TT
|
||
CLASS="REPLACEABLE"
|
||
><I
|
||
>process
|
||
substitution</I
|
||
></TT
|
||
> comes in.</P
|
||
><P
|
||
><I
|
||
CLASS="FIRSTTERM"
|
||
>Process substitution</I
|
||
> feeds the
|
||
output of a <A
|
||
HREF="special-chars.html#PROCESSREF"
|
||
>process</A
|
||
> (or
|
||
processes) into the <TT
|
||
CLASS="FILENAME"
|
||
>stdin</TT
|
||
> of another
|
||
process.</P
|
||
><P
|
||
></P
|
||
><DIV
|
||
CLASS="VARIABLELIST"
|
||
><P
|
||
><B
|
||
><A
|
||
NAME="COMMANDSPARENS1"
|
||
></A
|
||
>Template</B
|
||
></P
|
||
><DL
|
||
><DT
|
||
>Command list enclosed within parentheses</DT
|
||
><DD
|
||
><P
|
||
><B
|
||
CLASS="COMMAND"
|
||
>>(command_list)</B
|
||
></P
|
||
><P
|
||
><B
|
||
CLASS="COMMAND"
|
||
><(command_list)</B
|
||
></P
|
||
><P
|
||
>Process substitution uses
|
||
<TT
|
||
CLASS="FILENAME"
|
||
>/dev/fd/<n></TT
|
||
> files to send the
|
||
results of the process(es) within parentheses to another process.
|
||
<A
|
||
NAME="AEN18244"
|
||
HREF="#FTN.AEN18244"
|
||
><SPAN
|
||
CLASS="footnote"
|
||
>[1]</SPAN
|
||
></A
|
||
>
|
||
</P
|
||
><DIV
|
||
CLASS="CAUTION"
|
||
><P
|
||
></P
|
||
><TABLE
|
||
CLASS="CAUTION"
|
||
WIDTH="90%"
|
||
BORDER="0"
|
||
><TR
|
||
><TD
|
||
WIDTH="25"
|
||
ALIGN="CENTER"
|
||
VALIGN="TOP"
|
||
><IMG
|
||
SRC="../images/caution.gif"
|
||
HSPACE="5"
|
||
ALT="Caution"></TD
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
><P
|
||
>There is <EM
|
||
>no</EM
|
||
> space between the
|
||
the <SPAN
|
||
CLASS="QUOTE"
|
||
>"<"</SPAN
|
||
> or <SPAN
|
||
CLASS="QUOTE"
|
||
>">"</SPAN
|
||
> and the parentheses.
|
||
Space there would give an error message.</P
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
></DD
|
||
></DL
|
||
></DIV
|
||
><P
|
||
> <TABLE
|
||
BORDER="1"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="SCREEN"
|
||
><TT
|
||
CLASS="PROMPT"
|
||
>bash$ </TT
|
||
><TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>echo >(true)</B
|
||
></TT
|
||
>
|
||
<TT
|
||
CLASS="COMPUTEROUTPUT"
|
||
>/dev/fd/63</TT
|
||
>
|
||
|
||
<TT
|
||
CLASS="PROMPT"
|
||
>bash$ </TT
|
||
><TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>echo <(true)</B
|
||
></TT
|
||
>
|
||
<TT
|
||
CLASS="COMPUTEROUTPUT"
|
||
>/dev/fd/63</TT
|
||
>
|
||
|
||
<TT
|
||
CLASS="PROMPT"
|
||
>bash$ </TT
|
||
><TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>echo >(true) <(true)</B
|
||
></TT
|
||
>
|
||
<TT
|
||
CLASS="COMPUTEROUTPUT"
|
||
>/dev/fd/63 /dev/fd/62</TT
|
||
>
|
||
|
||
|
||
|
||
<TT
|
||
CLASS="PROMPT"
|
||
>bash$ </TT
|
||
><TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>wc <(cat /usr/share/dict/linux.words)</B
|
||
></TT
|
||
>
|
||
<TT
|
||
CLASS="COMPUTEROUTPUT"
|
||
> 483523 483523 4992010 /dev/fd/63</TT
|
||
>
|
||
|
||
<TT
|
||
CLASS="PROMPT"
|
||
>bash$ </TT
|
||
><TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>grep script /usr/share/dict/linux.words | wc</B
|
||
></TT
|
||
>
|
||
<TT
|
||
CLASS="COMPUTEROUTPUT"
|
||
> 262 262 3601</TT
|
||
>
|
||
|
||
<TT
|
||
CLASS="PROMPT"
|
||
>bash$ </TT
|
||
><TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>wc <(grep script /usr/share/dict/linux.words)</B
|
||
></TT
|
||
>
|
||
<TT
|
||
CLASS="COMPUTEROUTPUT"
|
||
> 262 262 3601 /dev/fd/63</TT
|
||
>
|
||
</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
>
|
||
</P
|
||
><DIV
|
||
CLASS="NOTE"
|
||
><P
|
||
></P
|
||
><TABLE
|
||
CLASS="NOTE"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
><TR
|
||
><TD
|
||
WIDTH="25"
|
||
ALIGN="CENTER"
|
||
VALIGN="TOP"
|
||
><IMG
|
||
SRC="../images/note.gif"
|
||
HSPACE="5"
|
||
ALT="Note"></TD
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
><P
|
||
> Bash creates a pipe with two <A
|
||
HREF="io-redirection.html#FDREF"
|
||
>file
|
||
descriptors</A
|
||
>, <TT
|
||
CLASS="FILENAME"
|
||
>--fIn</TT
|
||
> and
|
||
<TT
|
||
CLASS="FILENAME"
|
||
>fOut--</TT
|
||
>. The <TT
|
||
CLASS="FILENAME"
|
||
>stdin</TT
|
||
>
|
||
of <A
|
||
HREF="internal.html#TRUEREF"
|
||
>true</A
|
||
> connects
|
||
to <TT
|
||
CLASS="FILENAME"
|
||
>fOut</TT
|
||
> (dup2(fOut, 0)),
|
||
then Bash passes a <TT
|
||
CLASS="FILENAME"
|
||
>/dev/fd/fIn</TT
|
||
>
|
||
argument to <B
|
||
CLASS="COMMAND"
|
||
>echo</B
|
||
>. On systems lacking
|
||
<TT
|
||
CLASS="FILENAME"
|
||
>/dev/fd/<n></TT
|
||
> files, Bash may use
|
||
temporary files. (Thanks, S.C.)
|
||
</P
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
><P
|
||
>Process substitution can compare the output of two
|
||
different commands, or even the output of different options
|
||
to the same command.</P
|
||
><TABLE
|
||
BORDER="1"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="SCREEN"
|
||
><TT
|
||
CLASS="PROMPT"
|
||
>bash$ </TT
|
||
><TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>comm <(ls -l) <(ls -al)</B
|
||
></TT
|
||
>
|
||
<TT
|
||
CLASS="COMPUTEROUTPUT"
|
||
>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</TT
|
||
></PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
><P
|
||
><A
|
||
NAME="PCC2DIR"
|
||
></A
|
||
></P
|
||
><P
|
||
> Process substitution can compare the contents
|
||
of two directories -- to see which filenames are in one,
|
||
but not the other.</P
|
||
><P
|
||
> <TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>diff <(ls $first_directory) <(ls $second_directory)</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
>
|
||
</P
|
||
><P
|
||
>Some other usages and uses of process substitution:</P
|
||
><P
|
||
><A
|
||
NAME="PSFDSTDIN"
|
||
></A
|
||
></P
|
||
><P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>read -a list < <( od -Ad -w24 -t u2 /dev/urandom )
|
||
# Read a list of random numbers from /dev/urandom,
|
||
#+ process with "od"
|
||
#+ and feed into stdin of "read" . . .
|
||
|
||
# From "insertion-sort.bash" example script.
|
||
# Courtesy of JuanJo Ciarlante.</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></P
|
||
><P
|
||
><A
|
||
NAME="NETCATEXAMPLE"
|
||
></A
|
||
></P
|
||
><P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>PORT=6881 # bittorrent
|
||
|
||
# Scan the port to make sure nothing nefarious is going on.
|
||
netcat -l $PORT | tee>(md5sum ->mydata-orig.md5) |
|
||
gzip | tee>(md5sum - | sed 's/-$/mydata.lz2/'>mydata-gz.md5)>mydata.gz
|
||
|
||
# Check the decompression:
|
||
gzip -d<mydata.gz | md5sum -c mydata-orig.md5)
|
||
# The MD5sum of the original checks stdin and detects compression issues.
|
||
|
||
# Bill Davidsen contributed this example
|
||
#+ (with light edits by the ABS Guide author).</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></P
|
||
><P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>cat <(ls -l)
|
||
# Same as ls -l | cat
|
||
|
||
sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin)
|
||
# Lists all the files in the 3 main 'bin' directories, and sorts by filename.
|
||
# Note that three (count 'em) distinct commands are fed to 'sort'.
|
||
|
||
|
||
diff <(command1) <(command2) # Gives difference in command output.
|
||
|
||
tar cf >(bzip2 -c > file.tar.bz2) $directory_name
|
||
# Calls "tar cf /dev/fd/?? $directory_name", and "bzip2 -c > file.tar.bz2".
|
||
#
|
||
# Because of the /dev/fd/<n> system feature,
|
||
# the pipe between both commands does not need to be named.
|
||
#
|
||
# This can be emulated.
|
||
#
|
||
bzip2 -c < pipe > file.tar.bz2&
|
||
tar cf pipe $directory_name
|
||
rm pipe
|
||
# or
|
||
exec 3>&1
|
||
tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-
|
||
exec 3>&-
|
||
|
||
|
||
# Thanks, St<53>phane Chazelas</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></P
|
||
><P
|
||
><A
|
||
NAME="GOODREAD0"
|
||
></A
|
||
>Here is a method of circumventing the
|
||
problem of an <A
|
||
HREF="gotchas.html#BADREAD0"
|
||
><I
|
||
CLASS="FIRSTTERM"
|
||
>echo</I
|
||
>
|
||
piped to a <I
|
||
CLASS="FIRSTTERM"
|
||
>while-read loop</I
|
||
></A
|
||
> running
|
||
in a subshell.</P
|
||
><DIV
|
||
CLASS="EXAMPLE"
|
||
><A
|
||
NAME="WRPS"
|
||
></A
|
||
><P
|
||
><B
|
||
>Example 23-1. Code block redirection without forking</B
|
||
></P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>#!/bin/bash
|
||
# wr-ps.bash: while-read loop with process substitution.
|
||
|
||
# This example contributed by Tomas Pospisek.
|
||
# (Heavily edited by the ABS Guide author.)
|
||
|
||
echo
|
||
|
||
echo "random input" | while read i
|
||
do
|
||
global=3D": Not available outside the loop."
|
||
# ... because it runs in a subshell.
|
||
done
|
||
|
||
echo "\$global (from outside the subprocess) = $global"
|
||
# $global (from outside the subprocess) =
|
||
|
||
echo; echo "--"; echo
|
||
|
||
while read i
|
||
do
|
||
echo $i
|
||
global=3D": Available outside the loop."
|
||
# ... because it does NOT run in a subshell.
|
||
done < <( echo "random input" )
|
||
# ^ ^
|
||
|
||
echo "\$global (using process substitution) = $global"
|
||
# Random input
|
||
# $global (using process substitution) = 3D: Available outside the loop.
|
||
|
||
|
||
echo; echo "##########"; echo
|
||
|
||
|
||
|
||
# And likewise . . .
|
||
|
||
declare -a inloop
|
||
index=0
|
||
cat $0 | while read line
|
||
do
|
||
inloop[$index]="$line"
|
||
((index++))
|
||
# It runs in a subshell, so ...
|
||
done
|
||
echo "OUTPUT = "
|
||
echo ${inloop[*]} # ... nothing echoes.
|
||
|
||
|
||
echo; echo "--"; echo
|
||
|
||
|
||
declare -a outloop
|
||
index=0
|
||
while read line
|
||
do
|
||
outloop[$index]="$line"
|
||
((index++))
|
||
# It does NOT run in a subshell, so ...
|
||
done < <( cat $0 )
|
||
echo "OUTPUT = "
|
||
echo ${outloop[*]} # ... the entire script echoes.
|
||
|
||
exit $?</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
><P
|
||
><A
|
||
NAME="PSUBPIPING"
|
||
></A
|
||
>This is a similar example.</P
|
||
><DIV
|
||
CLASS="EXAMPLE"
|
||
><A
|
||
NAME="PSUBP"
|
||
></A
|
||
><P
|
||
><B
|
||
>Example 23-2. Redirecting the output of <I
|
||
CLASS="FIRSTTERM"
|
||
>process
|
||
substitution</I
|
||
> into a loop.</B
|
||
></P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>#!/bin/bash
|
||
# psub.bash
|
||
|
||
# As inspired by Diego Molina (thanks!).
|
||
|
||
declare -a array0
|
||
while read
|
||
do
|
||
array0[${#array0[@]}]="$REPLY"
|
||
done < <( sed -e 's/bash/CRASH-BANG!/' $0 | grep bin | awk '{print $1}' )
|
||
# Sets the default 'read' variable, $REPLY, by process substitution,
|
||
#+ then copies it into an array.
|
||
|
||
echo "${array0[@]}"
|
||
|
||
exit $?
|
||
|
||
# ====================================== #
|
||
|
||
bash psub.bash
|
||
|
||
#!/bin/CRASH-BANG! done #!/bin/CRASH-BANG!</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
><P
|
||
>A reader sent in the following interesting example of process
|
||
substitution.</P
|
||
><P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
># Script fragment taken from SuSE distribution:
|
||
|
||
# --------------------------------------------------------------#
|
||
while read des what mask iface; do
|
||
# Some commands ...
|
||
done < <(route -n)
|
||
# ^ ^ First < is redirection, second is process substitution.
|
||
|
||
# To test it, let's make it do something.
|
||
while read des what mask iface; do
|
||
echo $des $what $mask $iface
|
||
done < <(route -n)
|
||
|
||
# Output:
|
||
# Kernel IP routing table
|
||
# Destination Gateway Genmask Flags Metric Ref Use Iface
|
||
# 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
|
||
# --------------------------------------------------------------#
|
||
|
||
# As St<53>phane Chazelas points out,
|
||
#+ an easier-to-understand equivalent is:
|
||
route -n |
|
||
while read des what mask iface; do # Variables set from output of pipe.
|
||
echo $des $what $mask $iface
|
||
done # This yields the same output as above.
|
||
# However, as Ulrich Gayer points out . . .
|
||
#+ this simplified equivalent uses a subshell for the while loop,
|
||
#+ and therefore the variables disappear when the pipe terminates.
|
||
|
||
# --------------------------------------------------------------#
|
||
|
||
# However, Filip Moritz comments that there is a subtle difference
|
||
#+ between the above two examples, as the following shows.
|
||
|
||
(
|
||
route -n | while read x; do ((y++)); done
|
||
echo $y # $y is still unset
|
||
|
||
while read x; do ((y++)); done < <(route -n)
|
||
echo $y # $y has the number of lines of output of route -n
|
||
)
|
||
|
||
More generally spoken
|
||
(
|
||
: | x=x
|
||
# seems to start a subshell like
|
||
: | ( x=x )
|
||
# while
|
||
x=x < <(:)
|
||
# does not
|
||
)
|
||
|
||
# This is useful, when parsing csv and the like.
|
||
# That is, in effect, what the original SuSE code fragment does.</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></P
|
||
></DIV
|
||
><H3
|
||
CLASS="FOOTNOTES"
|
||
>Notes</H3
|
||
><TABLE
|
||
BORDER="0"
|
||
CLASS="FOOTNOTES"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
WIDTH="5%"
|
||
><A
|
||
NAME="FTN.AEN18244"
|
||
HREF="process-sub.html#AEN18244"
|
||
><SPAN
|
||
CLASS="footnote"
|
||
>[1]</SPAN
|
||
></A
|
||
></TD
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
WIDTH="95%"
|
||
><P
|
||
>This has the same effect as a
|
||
<A
|
||
HREF="extmisc.html#NAMEDPIPEREF"
|
||
>named pipe</A
|
||
> (temp
|
||
file), and, in fact, named pipes were at one time used
|
||
in process substitution.</P
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
><DIV
|
||
CLASS="NAVFOOTER"
|
||
><HR
|
||
ALIGN="LEFT"
|
||
WIDTH="100%"><TABLE
|
||
SUMMARY="Footer navigation table"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
CELLPADDING="0"
|
||
CELLSPACING="0"
|
||
><TR
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="left"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="restricted-sh.html"
|
||
ACCESSKEY="P"
|
||
>Prev</A
|
||
></TD
|
||
><TD
|
||
WIDTH="34%"
|
||
ALIGN="center"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="index.html"
|
||
ACCESSKEY="H"
|
||
>Home</A
|
||
></TD
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="right"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="functions.html"
|
||
ACCESSKEY="N"
|
||
>Next</A
|
||
></TD
|
||
></TR
|
||
><TR
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="left"
|
||
VALIGN="top"
|
||
>Restricted Shells</TD
|
||
><TD
|
||
WIDTH="34%"
|
||
ALIGN="center"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="part5.html"
|
||
ACCESSKEY="U"
|
||
>Up</A
|
||
></TD
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="right"
|
||
VALIGN="top"
|
||
>Functions</TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
></BODY
|
||
></HTML
|
||
> |