第119页 | Learning the Bash Shell | 阅读 ‧ 电子书库

同步阅读进度,多语言翻译,过滤屏幕蓝光,评论分享,更多完整功能,更好读书体验,试试 阅读 ‧ 电子书库

Here-documents

The << label redirector essentially forces the input to a command to be the shell's standard input, which is read until there is a line that contains only label. The input in between is called a here-document. Here-documents aren't very interesting when used from the command prompt. In fact, it's the same as the normal use of standard input except for the label. We could use a here-document to simulate the mail facility. When you send a message to someone with the mail utility, you end the message with a dot (.). The body of the message is saved in a file, msgfile:

$ cat >> msgfile << .
  > this is the text of
  > our message.
  > .

Here-documents are meant to be used from within shell scripts; they let you specify "batch" input to programs. A common use of here-documents is with simple text editors like ed. Task 7-1 is a programming task that uses a here-document in this way.

Task 7-1

The s file command in mail saves the current message in file. If the message came over a network (such as the Internet), then it has several header lines prepended that give information about network routing. Write a shell script that deletes the header lines from the file.

We can use ed to delete the header lines. To do this, we need to know something about the syntax of mail messages; specifically, that there is always a blank line between the header lines and the message text. The ed command 1,/^[]*$/d does the trick: it means, "Delete from line 1 until the first blank line." We also need the ed commands w (write the changed file) and q (quit). Here is the code that solves the task:

ed $1 << EOF
1,/^[ ]*$/d
w
q
EOF

The shell does parameter (variable) substitution and command substitution on text in a here-document, meaning that you can use shell variables and commands to customize the text. A good example of this is the bashbug script, which sends a bug report to the bash maintainer (see Chapter 11). Here is a stripped-down version:

MACHINE="i586"
OS="linux-gnu"
CC="gcc"
CFLAGS=" -DPROGRAM='bash' -DHOSTTYPE='i586' -DOSTYPE='linux-gnu' \
    -DMACHTYPE='i586-pc-linux-gnu' -DSHELL -DHAVE_CONFIG_H   -I. \
    -I. -I./lib -g -O2"
RELEASE="2.01"
PATCHLEVEL="0"
RELSTATUS="release"
MACHTYPE="i586-pc-linux-gnu"
    
TEMP=/tmp/bbug.$$
    
case "$RELSTATUS" in
alpha*|beta*)   BUGBASH=chet@po.cwru.edu ;;
*)              BUGBASH=bug-bash@prep.ai.mit.edu ;;
esac
    
BUGADDR="${1-$BUGBASH}"
    
UN=
if (uname) >/dev/null 2>&1; then
        UN=`uname -a`
fi
    
cat > $TEMP <<EOF
From: ${USER}
To: ${BUGADDR}
Subject: [50 character or so descriptive subject here (for reference)]
    
Configuration Information [Automatically generated, do not change]:
Machine: $MACHINE
OS: $OS
Compiler: $CC
Compilation CFLAGS: $CFLAGS
uname output: $UN
Machine Type: $MACHTYPE
    
bash Version: $RELEASE
Patch Level: $PATCHLEVEL
Release Status: $RELSTATUS
    
Description:
        [Detailed description of the problem, suggestion, or complaint.]
    
Repeat-By:
        [Describe the sequence of events that causes the problem
        to occur.]
    
Fix:
        [Description of how to fix the problem.  If you don't know a
        fix for the problem, don't include this section.]
EOF
    
vi $TEMP
    
mail $BUGADDR < $TEMP

The first eight lines are generated when bashbug is installed. The shell will then substitute the appropriate values for the variables in the text whenever the script is run.

The redirector << has two variations. First, you can prevent the shell from doing parameter and command substitution by surrounding the label in single or double quotes. In the above example, if you used the line cat > $TEMP <<`EOF', then text like $USER and $MACHINE would remain untouched (defeating the purpose of this particular script).

The second variation is <<-, which deletes leading TABs (but not blanks) from the here-document and the label line. This allows you to indent the here-document's text, making the shell script more readable:

cat > $TEMP <<-EOF
        From: ${USER}
        To: ${BUGADDR}
        Subject: [50 character or so descriptive subject here]
    
        Configuration Information [Automatically generated,
            do not change]:
        Machine: $MACHINE
        OS: $OS
        Compiler: $CC
        Compilation CFLAGS: $CFLAGS
        ...
EOF

Make sure you are careful when choosing your label so that it doesn't appear as an actual input line.

A slight variation on this is provided by the here string. It takes the form <<<word; the word is expanded and supplied on the standard input.

请支持我们,让我们可以支付服务器费用。
使用微信支付打赏


上一页 · 目录下一页


下载 · 书页 · 阅读 ‧ 电子书库