1. 标准输出
在Linux系统中运行的每一个进程都会默认关联到三个打开的文件上。这三个文件就是标准输入、标准输出、以及标准错误输出。
1.1 重定向输出
将命令的输出记录到磁盘上的文件中。
在bash中,重定向标准输出的语法
command > outputfile
例如把ls命令的输出保存到文件lsoutput.txt中。脚本内容:
#!/bin/bash
echo
#echo命令的输出没有被重定向,因此会输出到屏幕上
echo "Command 'ls' redirects its output into lsoutput.txt file"
#重定向ls命令的输出到文件lsoutput.txt中
ls > lsoutput.txt
#echo命令的输出没有被重定向,因此会输出到屏幕上
echo "...."
echo "Command 'ls' output completes,check lsoutput.txt file for 'ls' output."
echo
exit 0
注意:多个命令输出给一个文件
$date;df –h;output > list.output
1.2 重定向追加输出
不覆盖原有的内容,只追加新的内容。
在bash中,重定向标准输出的语法
command >> outputfile
案例:
#!/bin/bash
#输出到标准输出
echo
echo "Redirect standard output of command 'ls -C' into append.out"
echo
echo "So please check append.out file after running this script"
echo
#记录本脚本被运行的时间
date >> ~/append.out
#追加标准输出到文件append.out中
echo "The file list of $PWD is:" >> ~/append.out
#以列输出格式记录目录中的文件列表
ls -C >> ~/append.out
#在文件append.out中追加一个换行符
echo >> ~/append.out
exit 0
2. 标准输入
bash中标准输入重定向的语法格式:
command < inputfile
案例:
#!/bin/bash
#行号从数字1开始
linenumber=1
#从文件/etc/passwd中读取第一行
read oneline
#如果读取的是一个空行,则退出循环
while ["$oneline" != ""]
do
#打印行号及这行数据,然后打印一个换行符
echo -e "$linenumber:$oneline\n"
#行号加1
linenumber=`expr $linenumber+1`
#从文件/etc/passwd中读取下一行
read oneline
done
exit 0
3. 标准错误输出
3.1 把输出内容和错误信息分别存放两个文件
语法:
command > standard.output 2> standard.error
或者
command 1> standard.output 2> standard.error
案例:
#!/bin/bash
echo
echo "Create two files in current directory"
echo " 'separate.out' for standard output,"
echo " 'separate.err' for standard error output."
echo
echo "Please check their contents"
#同时列出存在的和不存在的文件,并把结果重定向到不同的文件
#如果没有指定文件描述符,默认使用文件描述符1,表示标准输出
ls /bin/bash /bin/ls /bin/dd /bin/this_file_not_exist >separate.out 2>separate.err
echo
exit 0
3.2 如果想把标准输出和标准错误输出都保存同一个文件
语法: 推荐使用第一种
command &> outputfile
或者
command >& outputfile
或者
command > outputfile 2>&1
案例:
#!/bin/bash
echo
echo "Create two files in current directory"
echo " 'separate.out' for standard output,"
echo " 'separate.err' for standard error output."
echo
echo "Please check their contents"
#列出存在和不存在的文件,并把标准输出和标准错误输出重定向到同一个文件中
ls /bin/bash /bin/ls /bin/dd /bin/this_file_not_exist &>same.out
#重定向标准错位输出到标准输出
ls /bin/bash /bin/ls /bin/dd /bin/this_file_not_exist >same.out 2>&1
#重定向标准输出到标准错位输出
ls /bin/bash /bin/ls /bin/dd /bin/this_file_not_exist 2>same.out 1>&2
echo
exit 0
3.3 把错误信息在屏幕屏蔽,也不保存
语法:
可以将标准错误输出重定向到文件/dev/null,/dev/null是一个虚拟出来的设备,不存在,所以保存在它里的数据会消失。
案例:
#!/bin/bash
echo
echo "Find some file in the whole filesystem,take very long time..."
echo "You can press Ctrl+C to abort this.."
#在整个文件系统中查找一个文件
find / -name "somefile" 2> /dev/null
exit 0
4. 管道
管道是把一个程序的输出数据作为另一个程序的输入数据。
管道语法:
command1 | command2 | command3 …
4.1 将一个文本作为一个参数运行脚本,传给另一个脚本运行
案例:
#!/bin/bash
#行号从数字1开始
linenumber=1
#文件/etc/passwd的内容通过管道传递到read命令中
cat $1|while read oneline
do
#打印行号及这行数据,然后打印一个换行符
echo -e "$linenumber:$oneline\n"
#行号加1
linenumber=`expr $linenumber+1`
done
exit 0
执行:
将/etc/passwd作为参数传递给pipeline.sh
$./pipeline.sh /etc/passwd
4.2 即把标准输出重定向到某个文件,也在屏幕显示
语法:
tee [OPTION] … [FILE] …
案例:
#!/bin/bash
#首先对文件/etc/passwd进行排序,然后添加行号
#再对标准输入进行复制,一个输出到标准输出
#另一个输出到文件sort.out中
sort /etc/passwd | cat -n | tee sort.out
exit 0
4.3 如何将目录下的后缀”.out”的文件删除
可以通过shell的命令替换功能,把find命令输出的文件路径列表当做rm命令的命令行参数。
案例:
#!/bin/bash
#使用命令替换$(command)的方法使得命令command的输出作为命令行的参数
#删除当前目录下所有文件名以.out结尾的文件
rm -i $(find . -name '*.out')
#另一种命令替换的方法
rm -i `find . -name '*.out'`
exit 0
命令替换有两种形式:
$(command)
或者
`command`
5. 块语句的输出和重定向
5.1 如何把所有命令的标准输出都重定向到某个文件中
案例:
#!/bin/bash
echo
echo "Block output is redirected to file 'block_current.out'."
#把多个命令的输出一起重定向到文件中
date;cd /etc;echo -n "Current Working dir:";pwd; > block_current.out
#打印当前工作目录
echo "Current Working dir:$PWD"
echo
exit 0
语法:
$command;command;… > output.file
5.2 修改文件的内容,再保存
读取用户指定的任意文本文件,在每一行的前面添加行号以后,保存到当前目录下以.lined作扩展名的文件中。
案例:
#!/bin/bash
echo
echo -n "This Program add line numbers for a text file. Specify a text file path:"
#读取用户输入的文件路径
read file
echo
echo "Processing each line of file $file...."
echo
count=0
#从完整路径中获得文件名
filename=`basename $file`
#每成功读取一行数据,while循环就会继续执行
while read line
do
#行号加1
count=$((count+1))
#在原始每一行数据的前面添加行号
echo $count:$line
#把文件中的数据作为while语句中read命令的标准输入
#同时把while循环的输出重定向到文件filename.lined中
done <$file> $filename.lined
echo "Output file is $filename.lined"
echo
exit 0
执行命令:
$sh block.sh
再输入/etc/hosts
$cat hosts.lined
注意:
(1) 不要遗漏{}两侧的空格。
(2)不要遗漏{}包围的语句块中最后一个命令后的分号(;)。
6. Here Document
Here Document是一种有特殊用处的代码块,它使用IO重定向的形式记录了一段临时的文本或交互的命令,并且把这些文本或命令一次地传递给一个程序或一个命令,作为它运行时的标准输入。
如果临时记录一些不需要保存的信息,如打印一些数据,该怎么办?
解决方案:可以使用bash提供的here document。
7. 文件描述符
在Shell命令行中执行任意一个命令,都会自动打开3个文件关联到所执行的命令,即标准输入、标准输出和标准错误输出。这些文件都通过一个整型数值来表示,即文件描述符。这三个文件所对应的文件描述符分别是STDIN 0,STDIN 1,STDIN 2.
7.1 一个脚本的输出分别重定向保存多个不同文件
省略