On-line Guides

How To Guides






Advanced Bash-Scripting Guide:
Prev Chapter 16. I/O RedirectionNext

16.1. Using exec

An exec <filename command redirects stdin to a file. From that point on, all stdin comes from that file, rather than its normal source (usually keyboard input). This provides a method of reading a file line by line and possibly parsing each line of input using sed and/or awk.

Example 16-1. Redirecting stdin using exec

#!/bin/bash
# Redirecting stdin using 'exec'.
exec 6<&0 # Link file descriptor #6 with stdin.
 # Saves stdin.
exec < data-file # stdin replaced by file "data-file"
read a1 # Reads first line of file "data-file".
read a2 # Reads second line of file "data-file."
echo
echo "Following lines read from file."
echo "-------------------------------"
echo $a1
echo $a2
echo; echo; echo
exec 0<&6 6<&-
# Now restore stdin from fd #6, where it had been saved,
#+ and close fd #6 ( 6<&- ) to free it for other processes to use.
#
# <&6 6<&- also works.
echo -n "Enter data "
read b1 # Now "read" functions as expected, reading from normal stdin.
echo "Input read from stdin."
echo "----------------------"
echo "b1 = $b1"
echo
exit 0

Similarly, an exec >filename command redirects stdout to a designated file. This sends all command output that would normally go to stdout to that file.

Example 16-2. Redirecting stdout using exec

#!/bin/bash
# reassign-stdout.sh
LOGFILE=logfile.txt
exec 6>&1 # Link file descriptor #6 with stdout.
 # Saves stdout.
exec > $LOGFILE # stdout replaced with file "logfile.txt".
# ----------------------------------------------------------- #
# All output from commands in this block sent to file $LOGFILE.
echo -n "Logfile: "
date
echo "-------------------------------------"
echo
echo "Output of \"ls -al\" command"
echo
ls -al
echo; echo
echo "Output of \"df\" command"
echo
df
# ----------------------------------------------------------- #
exec 1>&6 6>&- # Restore stdout and close file descriptor #6.
echo
echo "== stdout now restored to default == "
echo
ls -al
echo
exit 0

Example 16-3. Redirecting both stdin and stdout in the same script with exec

#!/bin/bash
# upperconv.sh
# Converts a specified input file to uppercase.
E_FILE_ACCESS=70
E_WRONG_ARGS=71
if [ ! -r "1ドル" ] # Is specified input file readable?
then
 echo "Can't read from input file!"
 echo "Usage: 0ドル input-file output-file"
 exit $E_FILE_ACCESS
fi # Will exit with same error
 #+ even if input file (1ドル) not specified (why?).
if [ -z "2ドル" ]
then
 echo "Need to specify output file."
 echo "Usage: 0ドル input-file output-file"
 exit $E_WRONG_ARGS
fi
exec 4<&0
exec < 1ドル # Will read from input file.
exec 7>&1
exec > 2ドル # Will write to output file.
 # Assumes output file writable (add check?).
# -----------------------------------------------
 cat - | tr a-z A-Z # Uppercase conversion.
# ^^^^^ # Reads from stdin.
# ^^^^^^^^^^ # Writes to stdout.
# However, both stdin and stdout were redirected.
# -----------------------------------------------
exec 1>&7 7>&- # Restore stout.
exec 0<&4 4<&- # Restore stdin.
# After restoration, the following line prints to stdout as expected.
echo "File \"1ドル\" written to \"2ドル\" as uppercase conversion."
exit 0

I/O redirection is a clever way of avoiding the dreaded inaccessible variables within a subshell problem.

Example 16-4. Avoiding a subshell

#!/bin/bash
# avoid-subshell.sh
# Suggested by Matthew Walker.
Lines=0
echo
cat myfile.txt | while read line;
 do {
 echo $line
 (( Lines++ )); # Incremented values of this variable
 #+ inaccessible outside loop.
 # Subshell problem.
 }
 done
echo "Number of lines read = $Lines" # 0
 # Wrong!
echo "------------------------"
exec 3<> myfile.txt
while read line <&3
do {
 echo "$line"
 (( Lines++ )); # Incremented values of this variable
 #+ accessible outside loop.
 # No subshell, no problem.
}
done
exec 3>&-
echo "Number of lines read = $Lines" # 8
echo
exit 0
# Lines below not seen by script.
$ cat myfile.txt
Line 1.
Line 2.
Line 3.
Line 4.
Line 5.
Line 6.
Line 7.
Line 8.

Prev Home Next
I/O RedirectionUp Redirecting Code Blocks
Published under the terms of the GNU General Public License Design by Interspire

AltStyle によって変換されたページ (->オリジナル) /