本章内容:
- 再探重定向
- 标准输入和输出
- 报告错误
- 丢弃数据
- 创建日志文件
15.1 理解输入和输出
将脚本输出导向特定位置。
15.1.1 标准文件描述符
Linux用文件描述符来标识每个对象。
===
15.1.2 重定向错误
1.只重定向错误
$ ls -al badfile 2> test4
2是STDERR的文件描述符
2.重定向错误和数据
$ ls -al test test2 test3 badtest 2> test6 1> test7
15.2 在脚本中重定向输出
15.2.1 临时重定向
必须要加&
#!/bin/bash
# testing STDERR messages
echo "This is an error" >&2
echo "This is normal output"
$ ./test8 2> test9
This is normal output
$ cat test9
This is an error
===
15.2.2 永久重定向
#!/bin/bash
# redirecting output to different locations
exec 2>testerror
echo "This is the start of the script"
echo "now redirecting all output to another location"
exec 1>testout
echo "This output should go to the testout file"
echo "but this should go to the testerror file" >&2
$
$ ./test11
This is the start of the script
now redirecting all output to another location
$ cat testout
This output should go to the testout file
$ cat testerror
but this should go to the testerror file
exec命令会启动一个新shell并将STDOUT文件描述重定向到文件。脚本中发给STDOUT的所有输出会被重向到文件。
15.3 在脚本中重定向输入
#!/bin/bash
# redirecting file input
exec 0< testfile
count=1
while read line
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
此时read从文件中读取数据,而不是键盘。
15.4 创建自己的重定向
15.4.1 创建输出文件描述符
#!/bin/bash
# using an alternative file descriptor
exec 3>test13out
echo "This should display on the monitor"
echo "and this should be stored in the file" >&3
echo "Then this should be back on the monitor"
$ ./test13
This should display on the monitor
Then this should be back on the monitor
$ cat test13out
and this should be stored in the file
===
15.4.2 重定向文件描述符
#!/bin/bash
# storing STDOUT, then coming back to it
exec 3>&1
exec 1>test14out
echo "This should store in the output file"
echo "along with this line."
exec 1>&3
echo "Now things should be back to normal"
$
$ ./test14
Now things should be back to normal
$ cat test14out
This should store in the output file
along with this line.
先把3定位到文件描述符1的当前位置,也就是STDOUT
===
15.4.3 创建输入文件描述符
#!/bin/bash
# redirecting input file descriptors
exec 6<&0
exec 0< testfile
count=1
while read line
do
echo"Line #$count:$line"
count=$[ $count + 1 ]
done
exec 0<&6
read -p "Are you done now? " answer
case $answer in
Y|y) echo "Goodbye";;
N|n) echo "Sorry, this is the end.";;
esac
===
15.4.4 创建读写文件描述符
===
15.4.5 关闭文件描述符
exec 3>&-
15.5 列出打开的文件描述符
lsof命令会列出整个Linux系统打开的所有文件描述符。
15.6 阻止命令输出
$ cat /dev/null > testfile
$ cat testfile
可用于将testfile中的数据清空,又不必删除这个文件
$ ls -al badfile test16 2> /dev/null
重定向到该位置的任何数据都会被丢掉
15.7 创建临时文件
15.7.1 创建临时本地文件
$ mktemp testing.XXXXXX
mktemp命令会用6个字符码代替这6个X,从而保证其在文件目录中是唯一的。
===
15.7.2 在/tmp 目录创建临时文件
$ mktemp -t test.XXXXXX
===
15.7.3 创建临时目录
mktemp -d dir.XXXXXX
#!/bin/bash
# using a temporary directory
tempdir=$(mktemp -d dir.XXXXXX)
cd $tempdir
tempfile1=$(mktemp temp.XXXXXX)
tempfile2=$(mktemp temp.XXXXXX)
exec 7> $tempfile1
exec 8> $tempfile2
echo "Sending data to directory $tempdir"
echo "This is a test line of data for $tempfile1" >&7
echo "This is a test line of data for $tempfile2" >&8
15.8 记录消息
tee filename
tee -a filename 追加数据
#!/bin/bash
# using the tee command for logging
tempfile=test22file
echo "This is the start of the test" | tee $tempfile
echo "This is the second line of the test" | tee -a $tempfile
echo "This is the end of the test" | tee -a $tempfile
$ ./test22
This is the start of the test
This is the second line of the test
This is the end of the test
$ cat test22file
This is the start of the test
This is the second line of the test
This is the end of the test
15.9 实例
#!/bin/bash
# read file and create INSERT statements for MySQL
outfile='members.sql'
IFS=','
while read lname fname address city state zip
do
cat >> $outfile << EOF
INSERT INTO members(lname,fname,address,city,state,zip) VALUES ('$lname', '$fname', '$address', '$city', '$state', '$zip');
EOF
done < ${1}
$ cat members.csv
Blum,Richard,123 Main St.,Chicago,IL,60601
Blum,Barbara,123 Main St.,Chicago,IL,60601
$ ./test23 < members.csv
$ cat members.sql
INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Blum',
'Richard', '123 Main St.', 'Chicago', 'IL', '60601');
INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Blum',
'Barbara', '123 Main St.', 'Chicago', 'IL', '60601');