文件描述符和重定向 重定向 > >> (>)将置空文件;(>>)在文件后添加 文件描述符 缩 写 描 述 0 STDIN 标准输入 1 STDOUT 标准输出 2 STDERR 标准错误 sh sw_cs.sh 1>stdout.log 2>stderr.log -- 标准输出放入stdout.log,标准错误放入stderr.log sh sw_cs.sh &>all.log -- 所有文件放入all.log(错误信息优先级更高,将排在前列) sh sw_cs.sh 2>/dev/null -- 不显示错误信息 tee命令一方面将数据重定向到文件,一方面将数据副本提供给标准输入 cat sw_cs.sh | tee output.sh | cat -n tee命令-a选项支持追加数据 cat sw_cs.sh | tee -a output.sh | cat -n 将文件重定向到命令 cmd < sw_cs.sh 重定向脚本内部文件 cat <<EOF> log.txt this is the first line this is the second line EOF 文本打开的三种模式: 只读模式(<) 截断模式(>) 追加模式(>>) #标准文件描述符 文件描述符 缩 写 描 述 0 STDIN 标准输入 1 STDOUT 标准输出 2 STDERR 标准错误 标准输入的两种方式 ①键入 cat ②文件重定向输入 cat < sw_cs.sh -- 效果和cat sw_cs.sh一样 标准输出(> >>) ls -al > sw_cs.sh who >> sw_cs.sh ls -al badfile > test.log -- shell对于错误消息的处理是跟普通输出分开 -- test.log数据为空,因为badfile不存在。报错的信息直接打印到控制台不会输出到test.log文件 重定向错误的几种处理方式 ①只重定向错误 ls -al badfile 2> test.log 将STDERR文件描述符值于重定向符号前 ②重定向错误和数据 ls -al test badfile 1> success.log 2> error.log -- 数据和错误分别输出到两个文件 ls -al test badfile &> total.log -- 数据和错误输出到同一个文件,错误信息会排在前面(错误信息有更高的优先级) #重定向 临时重定向(>&2) echo "This is an error" >&2 -- 可以制作错误日志 永久输出重定向(exec) #sw_cs.sh exec 1> success.txt exec 2> erro.txt echo "success" echo "erro" >&2 # 永久输入重定向 exec 0< testfile count=1 while read line do echo "Line #$count: $line" count=$[ $count + 1 ] done #创建自己的重定向 创建输出文件描述符 exec 3> testfile echo "success" echo "this is my testfile" >&3 exec 3>> testfileold -- 支持追加 重定向文件描述符 exec 3>&1 exec 1>test1 echo "test1" echo "test2" exec 1>&3 echo "test3" -- 执行该文件会打印test3,标准文件输出1重定向到3 创建输入文件描述符 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 创建读写文件描述符 exec 3<> testfile read line <&3 echo "Read: $line" -- 读入第一行 echo "This is a test line" >&3 -- 输出到第二行覆盖 关闭文件描述符 exec 3> test17file echo "This is a test line of data" >&3 exec 3>&- -- 关闭文件描述符 cat test17file exec 3> test17file -- 文件描述符3已经关闭,当再次开启将覆盖原有文件test17file echo "This'll be bad" >&3 列出打开的文件描述符 losf | more 阻止命令输出 ls -al > /dev/null -- /dev/null 文件的任何数据都不会保存,可快速清理文件数据cat /dev/null > test 创建临时文件 Linux使用/tmp目录来存放不需要永久保留的文件,系统启动时自动删除所有文件 创建本地临时文件 mktemp testing.XXXXXX -- ls -al testing*核查发现XXXXXX自动生成了唯一字符串 在/tmp 目录创建临时文件 mktemp -t test.XXXXXX -- -t 选项会强制 mktemp 命令来在系统的临时目录来创建该文件,如/tmp/testing.bfjbad 创建临时目录 mktemp -d dir.XXXXXX -- -d 选项告诉 mktemp 命令来创建一个临时目录而不是临时文件 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 -- 创建了一个临时文件,进入目录后创建了2个文件并写入数据 记录消息(tee) tee 命令相当于管道的一个T型接头。它将从 STDIN 过来的数据同时发往两处。一处是STDOUT ,另一处是 tee 命令行所指定的文件名 date | tee testfile -- 打印到控制台,同时输出到testfile(tee的每次使用会覆盖原未见testfile) date | tee -a testfile -- -a选项进行追加,到testfile 实例 #test 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} -- 读取文件,然后创建 INSERT语句将数据插入MySQL数据库 输入如下数据 $ cat members.csv Blum,Richard,123 Main St.,Chicago,IL,60601 Blum,Barbara,123 Main St.,Chicago,IL,60601 Bresnahan,Christine,456 Oak Ave.,Columbus,OH,43201 Bresnahan,Timothy,456 Oak Ave.,Columbus,OH,43201 $ test < members.csv sh test 得到 $ 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'); INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Bresnahan', 'Christine', '456 Oak Ave.', 'Columbus', 'OH', '43201'); INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Bresnahan', 'Timothy', '456 Oak Ave.', 'Columbus', 'OH', '43201'); $