[shell基础]——I/O重定向
文件标识符(FD)
1. Linux使用文件标识符(FD)来标识一个进程正在访问的特定文件
2. 当打开一个文件或创建一个文件时,Linux将返回一个文件标识符供其他操作引用
3. 文件标识符是一个小的非负整数,他是对应进程的
4. 当Linux系统启动一个进程时,将自动为该进程打开三个文件:标准输入(stdin)、标准输出(stdout)、标准错误输出(stderr)
5. 该进程如果要打开其他的输入或输出文件,则从整数3开始标识
我们知道,/proc/N/fd目录包含了进程pid为N的、相关的所有的文件描述符 我们可以看看这个目录下有什么 # ll /proc/1/fd/ 总用量 0 lrwx------ 1 root root 64 7月 25 11:22 0 -> /dev/null lrwx------ 1 root root 64 7月 25 11:22 1 -> /dev/null lrwx------ 1 root root 64 7月 25 11:22 2 -> /dev/null lr-x------ 1 root root 64 7月 25 11:22 3 -> pipe:[7399] l-wx------ 1 root root 64 7月 25 11:22 4 -> pipe:[7399] lr-x------ 1 root root 64 7月 25 11:22 5 -> inotify lr-x------ 1 root root 64 7月 25 11:22 6 -> inotify lrwx------ 1 root root 64 7月 25 11:22 7 -> socket:[7400] lrwx------ 1 root root 64 7月 25 11:22 9 -> socket:[11307]
stdin、stdout、stderr
1. 标准输入(stdin)、标准输出(stdout)、标准错误输出(stderr)三者的关系是?
shell命令从"标准输入"读取输入数据,将输出送到"标准输出",如果命令在执行过程中发生错误则将错误信息输出到”标准错误输出“
2. stdin、stdout、stderr是怎么来的?
# ll /dev/stdin lrwxrwxrwx 1 root root 15 7月 25 2016 /dev/stdin -> /proc/self/fd/0 # ll /dev/stdout lrwxrwxrwx 1 root root 15 7月 25 2016 /dev/stdout -> /proc/self/fd/1 # ll /dev/stderr lrwxrwxrwx 1 root root 15 7月 25 2016 /dev/stderr -> /proc/self/fd/2
输入输出重定向的符号及其用法
1. 输出重定向:> >> >|
在脚本中用的最多的就是把一条命令的执行结果输出重定向到一个文本文件中去
# cat > newfile --->#把输入重定向到newfile这个文本文件中去 hello this is a test --->#按ctrl+d结束 # cat newfile hello this is a test 注意理解>和>>的区别 # echo "追加内容" >>newfile # cat newfile hello this is a test 追加内容 # echo "覆盖内容" >newfile # cat newfile 覆盖内容 >|与shell的noclobber选项有关系,表示强制覆盖文件 # set -o noclobber --->#开启此选项 # echo "试图覆盖" >newfile --->#试图覆盖newfile时报错 bash: newfile: cannot overwrite existing file # echo "强制覆盖" >|newfile --->#可以使用>|强制覆盖 # cat newfile 强制覆盖
2. 重定向标准输出和标准错误的方法
# ll 1.txt 2.txt ls: 无法访问2.txt: 没有那个文件或目录 --->#这是一条标准错误输出 -rw-r--r-- 1 root root 0 7月 25 14:52 1.txt --->#这是一条标准输出 把错误输出重定向,不显示在屏幕上 # ll 1.txt 2.txt 2>/dev/null -rw-r--r-- 1 root root 0 7月 25 14:52 1.txt 把标准输出重定向,不显示在屏幕上 # ll 1.txt 2.txt 1>/dev/null ls: 无法访问2.txt: 没有那个文件或目录 把标准输出和错误输出分别重定向到不同的文件中 # ll 1.txt 2.txt 1>outfile 2>errfile # cat outfile -rw-r--r-- 1 root root 0 7月 25 14:52 1.txt # cat errfile ls: 无法访问2.txt: 没有那个文件或目录 脚本中最常用的:就是把所有输出都不显示在屏幕上 # ll 1.txt 2.txt &>/dev/null # ll 1.txt 2.txt >/dev/null 2>&1
3. 在脚本中,while/for/until/if语句的重定向可以按行读取文本文件中的内容,以此实现某种处理
===while循环=== while read line do echo $line done < newfile --->#将newfile文本中的内容按行读取 ===for循环=== ls /etc >loggg maxline=`wc -l <loggg` for filename in `seq $maxline` do read filename echo $filename done <logg
4. 标准输入到标准输出的传递: |(管道)、exec、xargs
(1) -exec 执行后面的命令(其中, “{}”表示存放find命令查找的结果, “\;”表示结束标志
(2) xargs 是将前面命令的输出做为参数送给后面的命令使用
-n 后面跟数字num,限制xargs后面的命令接收参数时按num个接收
# find /boot -name "vmlinuz*" | xargs ls -l -rwxr-xr-x. 1 root root 4044560 Jan 30 2013 /boot/vmlinuz-2.6.32-358.el6.x86_64 # find /boot -name "vmlinuz*" -exec ls -l {} \; -rwxr-xr-x. 1 root root 4044560 Jan 30 2013 /boot/vmlinuz-2.6.32-358.el6.x86_64