Linux输入输出重定向的原理和实现
linux标准输入输出重定向到串口设置指南
Linux标准输入输出重定向到串口指南邮箱:追风哥455546798@描述:设置linux系统的标准输入输出到com0(console口),以便维护人员在无网络、无显示器的情况下对系统维护。
在各文件(/etc/grub.conf、/etc/inittab、/etc/securetty)中添加红色部分!文件修改完成后reboot系统即可在com0口看到标准输入输出信息。
1、grub.conf 文件配置[root@localhost etc]# more grub.conf# grub.conf generated by anaconda## Note that you do not have to rerun grub after making changes to this file# NOTICE: You do not have a /boot partition. This means that# all kernel and initrd paths are relative to /, eg.# root (hd0,0)# kernel /boot/vmlinuz-version ro root=/dev/sda1# initrd /boot/initrd-[generic-]version.img#boot=/dev/sdadefault=2timeout=10splashimage=(hd0,0)/boot/grub/splash.xpm.gzhiddenmenuserial --unit=0 --speed=115200 --word=8 --parity=no --stop=1terminal --timeout=10 serial consoletitle Red Hat Enterprise Linux (2.6.32-71.el6.i686)root (hd0,0)kernel /boot/vmlinuz-2.6.32-71.el6.i686 roroot=UUID=0cdc97d9-4515-461c-9691-91a03b9a41ea console=ttyS0,115200n8 rd_NO_LUKS rd_NO_LVMrd_NO_MD rd_NO_DMLANG=zh_CN.UTF-8 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quietconsole=tty0initrd /boot/initramfs-2.6.32-71.el6.i686.img2、inittab 文件配置[root@localhost etc]# more inittabid:3:initdefault:S0:2345:respawn:/sbin/agetty -L -f /etc/issueserial 115200 ttyS0 vt100//说明在文件末尾添加S0:2345:xxxx行3、securetty 文件配置[root@localhost etc]# more securetty vc/10tty1tty2ttyS0//说明在文件末尾添加ttyS0。
linux管道和重定向使用实验报告
附件5:西南民族大学学生实验报告2018 ------2019 学年第1学期课程名称:Unix/Linux环境编程任课教师:学院:专业:年级:班级:学号:姓名:同组人:西南民族大学学生实验报告学院:实验室名称:实验时间:姓名:专业:班级:学号:实验项目名称:管道和重定向使用、账户验证文件内容实验成绩:教师签名:实验项目报告内容(1、实验背景(目的、意义及原理等);2、材料与方法;3、实验主要过程与结果;4、分析讨论;5、教师评阅,页数不够可加页)。
1、实验背景(目的、意义及原理等)实验内容:管道和重定向使用、账户验证文件内容。
实验目的:练习shell命令中的管道和输入输出重定向,以掌握linux集合小程序完成大功能的思想理念。
了解四个账户验证文件的文件名、位置、内容,以深刻理解linux的账户信息、口令时效、组成员。
实验重点:掌握linux编程中管道和输入输出重定向的使用。
2、材料与方法实验设备:安装有Windows操作系统的电脑、Linux系统iso文件、VMware虚拟机软件。
1)实验主要过程与结果①输入输出重定向举例截图②重定向举例③输出重定向与空设备④利用ctrl+z挂起的tail进程,查看带有重定向功能的进程fd指向⑤管道的引入⑥T型管道⑦命令替换⑧账户信息验证口令文件/etc/passwd组账号文件/etc/group分析讨论这次使用linux系统进行指令操作的实验,通过这次实验基本掌握了linux 系统的工作环境和操作流程,根据老师提供的操作指导一步一步对各项指令进行了验证,在得出结果显示的同时进行了数据分析。
Linux基本操作实验中的指令很多,需要自己通过实验理解记忆,在理解的同时深化各指令的应用,最终通过实验来实现对linux基本指令操作的目的。
在实验过程中,经常会因为命令的格式敲得不对,导致命令出错,比如漏掉空格,多一个空格,所以做实验的过程中一定要认真敲命令。
管道和输入输出重定向中体现的集合小程序完成大功能思想一般情况,我们的标准输入是键盘,标准输出是终端显示器;但是在很多情况,我们需要从文件中读取数据作为输入,然后将输出数据保存在文件中。
linux的标准输入重定向例子
linux的标准输入重定向例子
标准输入重定向是将命令的输入从键盘转向其他来源,例如文件或其他命令的输出。
以下是Linux中的标准输入重定向的几个例子:
1. 从文件中读取输入:
```shell
$ command < file.txt
```
这个命令将会将`file.txt`的内容作为`command`命令的输入。
2. 通过管道将命令的输出作为输入:
```shell
$ command1 | command2
```
这个命令将会将`command1`的输出作为`command2`的输入。
3. 结合使用管道和重定向:
```shell
$ command1 | command2 < file.txt
```
这个命令将会将`command1`的输出作为`command2`的输入,而且`command2`的输入还会从
`file.txt`中读取。
4. 使用here文档:
```shell
$ command <<EOF
> input text
> input text
> more input text
> EOF
```
这个命令将会将`input text`作为输入传递给`command`命令。
`<<EOF`表示输入将从当前行延续到文件结尾的`EOF`行。
这些例子展示了如何使用标准输入重定向来改变命令的输入来源。
请注意,标准输入重定向使用`<`符号来指定重定向来源。
linuxshell之终端读写文件数据流和重定向,,《,》
linuxshell之终端读写⽂件数据流和重定向,,《,》终端实现⽂件中数据流的读写;重定向命令列表如下:命令说明command > file将输出重定向到 file。
将终端数据写到⽂件file中command < file将输⼊重定向到 file。
将⽂件command >> file将输出以追加的⽅式重定向到 file。
n > file将⽂件描述符为 n 的⽂件重定向到 file。
n >> file将⽂件描述符为 n 的⽂件以追加的⽅式重定向到 file。
n >& m将输出⽂件 m 和 n 合并。
n <& m将输⼊⽂件 m 和 n 合并。
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输⼊。
需要注意的是⽂件描述符 0 通常是标准输⼊(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
这⾥可以⽤于⽇志打印到⽂件;输出重定向重定向⼀般通过在命令间插⼊特定的符号来实现。
特别的,这些符号的语法如下所⽰:command1 > file1上⾯这个命令执⾏command1然后将输出的内容存⼊file1。
注意任何file1内的已经存在的内容将被新内容替代。
如果要将新内容添加在⽂件末尾,请使⽤>>操作符。
实例执⾏下⾯的 who 命令,它将命令的完整的输出重定向在⽤户⽂件中(users):$ who > users执⾏后,并没有在终端输出信息,这是因为输出已被从默认的标准输出设备(终端)重定向到指定的⽂件。
你可以使⽤ cat 命令查看⽂件内容:$ cat users_mbsetupuser console Oct 31 17:35tianqixin console Oct 31 17:35tianqixin ttys000 Dec 1 11:33输出重定向会覆盖⽂件内容,请看下⾯的例⼦:$ echo "菜鸟教程:" > users$ cat users菜鸟教程:$如果不希望⽂件内容被覆盖,可以使⽤ >> 追加到⽂件末尾,例如:$ echo "菜鸟教程:" >> users$ cat users菜鸟教程:菜鸟教程:$输⼊重定向和输出重定向⼀样,Unix 命令也可以从⽂件获取输⼊,语法为:command1 < file1这样,本来需要从键盘获取输⼊的命令会转移到⽂件读取内容。
Linux终端命令的输出重定向技巧让你的命令更灵活
Linux终端命令的输出重定向技巧让你的命令更灵活在Linux系统中,命令行终端是我们与操作系统进行交互的主要方式之一。
而能够灵活处理终端命令的输出结果,则是每一个Linux系统用户都应该掌握的技巧之一。
本文将介绍几种常见的输出重定向技巧,让你的命令操作更加方便和高效。
1. 标准输出重定向标准输出是命令行终端上的输出结果,默认情况下会被打印在屏幕上。
但是,我们可以使用输出重定向符号 ">" 将标准输出定向到指定文件中,而不是显示在终端上。
例如,我们可以将"ls"命令的输出结果重定向到一个名为"filelist.txt"的文件中:```ls > filelist.txt```这样,"ls"命令的结果就会被保存在"filelist.txt"文件中,而不会在终端上显示。
2. 追加输出重定向除了使用">"符号进行标准输出重定向外,还可以使用">>"符号来实现追加输出重定向。
不同于"">"符号会覆盖原有文件内容,">>"符号会将结果追加到文件末尾。
例如,我们可以将"ls"命令的输出结果追加到已存在的"filelist.txt"文件中:```ls >> filelist.txt```这样,"ls"命令的结果会被添加到"filelist.txt"文件的末尾。
3. 错误输出重定向除了标准输出外,命令行终端还存在另外一种输出叫做错误输出(stderr)。
通常情况下,错误输出会打印在终端上。
如果我们希望将错误输出保存到文件中,可以使用"2>"符号进行错误输出重定向。
Linux命令高级技巧使用tee和重定向进行输出管道和文件保存
Linux命令高级技巧使用tee和重定向进行输出管道和文件保存Linux命令高级技巧:使用tee和重定向进行输出管道和文件保存在Linux系统中,命令行是我们日常工作的重要工具。
熟练掌握Linux命令的使用,能够提高我们的效率和操作的灵活性。
在此,我们将介绍两个高级技巧,即使用tee命令和重定向来进行输出的管道处理和文件保存。
一、使用tee命令进行输出管道处理在Linux中,我们经常需要将命令的输出结果通过管道传递给其他命令进行进一步处理,tee命令就可以派上用场。
tee命令能够将标准输入的内容同时输出到标准输出和指定的文件中。
其基本用法如下:``` shellcommand | tee file```其中,command表示前一个命令的输出内容,|表示管道符,tee表示将输出内容写入文件的命令,file表示指定的输出文件。
例如,我们可以通过以下命令将ls命令的输出结果保存到txt文件中并在终端显示:``` shellls | tee result.txt```通过这个命令,ls命令的输出结果将会同时显示在终端上并保存到result.txt文件中,方便我们查看和分析。
二、使用重定向进行输出文件保存除了使用tee命令进行管道处理外,我们还可以使用重定向来将命令的输出结果保存到文件中。
重定向有两种方式:一种是将输出结果覆盖写入文件,另一种是将输出结果追加写入文件。
1. 将输出结果覆盖写入文件可以使用以下方式将命令的输出结果覆盖写入文件:``` shellcommand > file```其中,command为要执行的命令,>为重定向符号,file为要保存输出结果的文件名。
例如,我们可以将date命令的输出结果保存到datetime.txt文件中:``` shelldate > datetime.txt```通过这个命令,date命令的输出结果将会覆盖写入datetime.txt文件中。
Linux之重定向
Linux之重定向1,Linux中的重定向到底是个什么呢?Linux中的重定向就是将原本要输出到屏幕中的数据信息,重新指向某个特定的⽂件中,或者定向到⿊洞(/dev/null)中。
1.2重定向有什么⽤呢?1,当程序执⾏输出的信息⽐较多时,需要保存下来在进⾏分页查看。
2,后台执⾏的程序⼀般都会有输出,不希望它输出⼲扰到终端。
3,执⾏定时的备份任务,希望备份的结果保留下来时。
4,当重复创建⽤户,会提⽰⼀些错误信息,可以直接将信息丢弃。
5,希望将错误⽇志与正确⽇志,分别输出保存到不同⽂件时。
1.3 标准输⼊与输出当进程操作⼀个⽂件时:1,⾸先进程是⽆法直接访问硬件的,需要借助内核来访问⽂件2,⽽内核kernel需要利⽤⽂件描述符(file descriptor)来访问⽂件。
总结:进程---通过--->⽂件描述符(⾮负整数)--访问---》⽂件名称;进程使⽤⽂件描述符来管理打开的⽂件对应关系。
第⼀步:运⾏ tail -f /etc/passwd第⼆部:通过⽂件描述符3--->/etc/passwd-->inode-->block第三步:正确输出--->默认情况下通过⽂件描述符1--->当前终端 1>(改变输出的位置,⽂件,⿊洞)第四步:错误输出--->默认情况下通过⽂件描述符2---》当前终端 2>(错误输出)通常程序访问⼀个⽂件⾄少会打开三个标准⽂件,分别是标准输⼊,标准输出,错误输出。
进程将从标准输⼊中得到数据,将正常输出打印⾄屏幕终端,将错误的输出信息也打印⾄屏幕终端。
名称⽂件描述符作⽤标准输⼊(STDIN)0默认是键盘,也可以是⽂件或其他命令的输出标准输出(STDOUT)1默认输出到屏幕。
错误输出(STDERR)2默认输出到屏幕⽂件名称(filename)3+2,输出重定向案例输出重定向,改变输出内容的位置。
输出重定向有如下⼏种⽅式,如表格所⽰:类型操作符⽤途标准覆盖输出重定向1>将程序输出的正确结果输出到指定到⽂件中,会覆盖⽂件原有的内容标准追加输出重定向1>>将程序输出的正确结果以追加的⽅式输出到指定⽂件错误覆盖输出重定向2>将程序的错误结果输出到执⾏的⽂件中,会覆盖⽂件原有的内容错误追加输出重定向2>>将程序输出的错误结果以追加的⽅式输出到执⾏的⽂件2.1,案例1,-标准输出重定向标准输出重定向⽰例1,如果⽂件不存在则创建2,如果⽂件存在则清空内容[root@: ~]#> text.txt[root@: ~]#ifconfig echo > edu.txt2.2案例-标准追加输出重定向标准追加输出重定向⽰例1,如果⽂件不存在则创建2,如果⽂件存在则在⽂件尾部添加内容[root@: ~]#echo "hello linux" >>if2.3案例3-错误输出重定向错误输出重定向1,正确输出及错误输出⾄相同⽂件2,正确输出及错误输出⾄不同的⽂件[root@: ~]#find /etc -name "*.conf" 1>ok 2>ok[root@: ~]#find /etc -name "*.conf" 1>ok 2>error2.4案例4-混合和输出重定向混合输出重定向1,将正确输出和错误输出混合⾄同⼀⽂件2,将两个⽂件内容组合为⼀个⽂件[root@: ~]#find /etc/ -name "*.conf" &>ab[root@: ~]#cat ab >c*正确和错误都输⼊到相同位置[root@: ~]#ls /root/ /error >ab 2>&12.5,案例5-将内容输出⾄⿊洞[root@: ~]#ls /root/ /error >ab 2>/dev/null[root@: ~]#ls /root/ /error >ab &>/dev/null3,输⼊重定向案例输⼊重定向:指的是"重新指定设备"来"代替键盘"作为新的输⼊设备;3.1输⼊重定向⽰例1,通过输⼊重定向读取⽂件内容;[root@: ~]#cat < /etc/hosts2,通过输⼊重定向读⼊多⾏内容;[root@: ~]# cat <<EOF[root@: ~]#cat <<EOF> 1> 2> 3> 4> 5> EOF #只要不出现EOF则可以⼀直输⼊3,通过输⼊重定向数据导⼊⾄数据库中;[root@: ~]#mysql -uroot -p < /opt/wordpress.sql3.2脚本输⼊重定向使⽤输⼊重定向打印安装服务的菜单导航栏;[root@: ~]# cat install.sh#!/usr/bin/bashcat <<-EOF-----------主菜单---------| 1)安装nginx || 2)安装php || 3)退出 |-----------------------EOFread -p "请选择你要安装的软件编号[1|2|3]:"3.3输⼊重定向场景1,恢复数据时2,脚本打印菜单3,cat写⼊⽂件时;vim输出重定向正确输出:1>:覆盖(先清空,后写⼊)1>>:直接写⼊⽂件的尾部(末尾)错误输出2>:覆盖(先清空,后写⼊)2>>:直接写⼊⽂件的尾部(末尾)混合输出&>/dev/null&>>/dev/null1>/dev/null 2>&14,进程管道技术4.1 什么是管道管道操作符合"|",主要⽤来链接左右两个命令,将左侧命令的【标准输出】,交给右侧命令的【标准输⼊】⽆法传递错误的标准输出给后者命令管道命令符可以让⼤家进⼀步掌握命令之间的搭配使⽤⽅法,进⼀步提⾼命令输出值的处理效率4.2管道流程⽰意图格式:cmd1 | cmd2 [...|cndn]4.3管道使⽤案例案例1:将/etc/passwd中的⽤户按UID⼤⼩排序[root@: ~]#sort -t ":" -k3 -n /etc/passwd[root@: ~]#sort -t ":" -k3 -n /etc/passwd -r[root@: ~]#sort -t ":" -k3 -n /etc/passwd |head案例2:统计当前/etc/passwd中⽤户使⽤的shell类型#取出第七列(shell)|排序(相同的归类)|去重[root@: ~]#awk -F:`{pint $7}` /etc/passwd |sort |uniq -c案例3:打印并输出当前所有主机⽹卡的IP地址[root@: ~]#ip addr |grep 'inet' |awk '{print $2}' |awk -F "/" '{print $1}'4.4.1,tee与xargs[root@: ~]#ip addr |grep 'inet' |tee ip.txt |awk -F "/" '{print $1}' |awk '{print $2}'[root@: ~]#cat ip.txt4.4.2,管道中使⽤xargsxargs参数传递,主要让⼀些不⽀持管道的命令可以使⽤管道技术[root@: ~]#which cat |xargs ls -l-rwxr-xr-x. 1 root root 54080 Apr 11 2018 /usr/bin/cat[root@: ~]# xargs rm -fv。
标准输出重定向
标准输出重定向标准输出重定向是指将程序的标准输出流重定向到其他地方,而不是默认的终端控制台。
这个技术在实际的软件开发中非常有用,可以帮助我们将程序的输出保存到文件中,或者发送到其他程序进行处理,从而实现更灵活的应用场景。
在Unix/Linux系统中,标准输出重定向是通过一些特殊的符号来实现的。
最常用的符号包括">"和">>",它们分别表示覆盖写和追加写。
通过这些符号,我们可以将程序的标准输出重定向到指定的文件中,实现输出结果的保存和管理。
在Windows系统中,标准输出重定向同样是非常重要的。
通过命令提示符中的一些特定命令,我们可以实现标准输出的重定向操作。
这些命令包括">"和">>",用法与Unix/Linux系统中的相似。
标准输出重定向的应用场景非常广泛。
比如,当我们需要将程序的输出结果保存到日志文件中时,就可以使用标准输出重定向。
又比如,当我们需要将程序的输出结果发送给其他程序进行处理时,同样可以使用标准输出重定向。
通过这种方式,我们可以实现程序输出结果的灵活处理和管理。
除了简单的输出重定向外,标准输出重定向还可以结合管道操作,实现更为复杂的应用场景。
通过管道操作,我们可以将一个程序的输出结果直接发送给另一个程序进行处理,从而实现更为复杂的数据处理和管理。
在实际的软件开发中,标准输出重定向是非常常见的技术。
通过这种技术,我们可以实现程序输出结果的灵活处理和管理,从而为用户提供更为优质的服务和体验。
因此,掌握标准输出重定向的技术是非常重要的,可以帮助我们更好地开发和管理软件系统。
总的来说,标准输出重定向是软件开发中非常重要的技术。
通过这种技术,我们可以实现程序输出结果的灵活处理和管理,从而为用户提供更为优质的服务和体验。
在实际的开发工作中,我们应该充分利用标准输出重定向的技术,从而更好地开发和管理软件系统。
标准错误输出重定向
标准错误输出重定向在编程过程中,我们经常会遇到错误输出的情况。
而标准错误输出重定向则是一种将错误信息输出到指定位置的技术。
本文将介绍标准错误输出重定向的基本概念、用法和实际操作,帮助读者更好地理解和应用这一技术。
一、基本概念。
标准错误输出重定向是指将程序的错误信息输出到指定位置,而不是默认的输出设备。
在大多数情况下,程序的错误信息会被输出到标准错误输出设备(通常是屏幕),这样会给用户带来不便。
通过标准错误输出重定向,我们可以将错误信息输出到文件或者其他设备,以便后续查看和分析。
二、用法。
在Unix/Linux系统中,可以使用符号“2>”来进行标准错误输出重定向。
例如,我们可以将错误信息输出到一个名为error.log的文件中:```。
./myprogram 2> error.log。
```。
这样,程序的错误信息就会被重定向到error.log文件中,而不会在屏幕上显示。
在Windows系统中,标准错误输出重定向的用法类似。
可以使用符号“2>”来实现:```。
myprogram.exe 2> error.log。
```。
三、实际操作。
下面我们通过一个简单的例子来演示标准错误输出重定向的实际操作。
假设我们有一个名为test.py的Python程序,内容如下:```。
print("Hello, world!")。
x = 1 / 0。
```。
这个程序首先会输出"Hello, world!",然后会出现一个除以零的错误,导致程序中断并输出错误信息。
现在,我们可以通过标准错误输出重定向将错误信息输出到一个名为error.log 的文件中。
在命令行中输入以下命令:```。
python test.py 2> error.log。
```。
这样,程序的错误信息就会被重定向到error.log文件中。
我们可以打开error.log文件查看错误信息:```。
linux. expect 实现原理
linux. expect 实现原理
Expect 是一个自动化工具,用于自动化交互式应用程序的输入和输出。
在Linux 系统中,Expect 可以用于自动化诸如ssh、ftp、passwd、telnet、fsck、rlogin 和tip 等交互式应用程序的操作。
Expect 的实现原理主要包括以下几个步骤:
1. 启动应用程序:Expect 启动要自动化的应用程序,并与其建立连接。
2. 读取输出:Expect 读取应用程序的输出,并根据输出内容进行相应的处理。
3. 发送输入:根据应用程序的输出,Expect 自动发送相应的输入。
4. 等待结束:当应用程序结束时,Expect 会捕获其退出状态,并结束自动化操作。
Expect 的实现原理主要依赖于以下技术:
1. 进程管理:Expect 通过进程管理技术来启动、监控和结束应用程序。
2. 输入/输出重定向:Expect 通过输入/输出重定向技术来读取和发送数据。
3. 正则表达式:Expect 使用正则表达式来匹配和处理应用程序的输出。
4. 条件判断:Expect 使用条件判断语句来根据应用程序的输出发送相应的输入。
总之,Expect 的实现原理主要是通过进程管理、输入/输出重定向、正则表达式和条件判断等技术来实现自动化交互式应用程序的操作。
优化Linux命令使用tee命令将输出重定向到文件和屏幕
优化Linux命令使用tee命令将输出重定向到文件和屏幕Linux提供了丰富而强大的命令行工具,其中tee命令是一种非常实用的工具,它可以将输入同时输出到文件和屏幕。
本文将介绍如何优化Linux命令使用tee命令,以实现输出重定向的效果。
一、什么是tee命令tee命令是一种常用的Linux命令,它用于将输入同时输出到文件和屏幕。
它的基本语法如下:```命令 | tee 文件名```其中,命令表示要执行的命令,|(竖线)表示管道符号,用于将命令的输出输入到tee命令中,文件名表示输出到文件的文件名。
二、实例演示为了更好地理解tee命令的用法,下面将通过几个实例演示tee命令的功能和用法。
1. 输出到文件首先,我们来演示如何将命令的输出重定向到文件。
假设我们要查看系统中的进程状态,并将结果保存到文件proc_status.txt中,可以使用以下命令:```ps -ef | tee proc_status.txt```这样,ps命令的输出将会保存到proc_status.txt文件中,并且同时显示在屏幕上。
2. 追加到文件有时候,我们希望将命令的输出追加到文件中而不是覆盖原有内容。
可以使用tee命令的-a选项来实现这个功能,例如:```who | tee -a user_list.txt```这样,who命令的输出将会追加到user_list.txt文件中,不会覆盖原有内容。
3. 仅输出到文件有时候,我们希望将命令的输出只保存到文件中而不在屏幕上显示。
可以使用tee命令的/dev/null选项来实现这个功能,例如:```ls | tee /dev/null > file_list.txt```这样,ls命令的输出将会保存到file_list.txt文件中,而不会在屏幕上显示。
三、优化使用tee命令的技巧除了基本的用法之外,还有一些技巧可以帮助我们更好地使用tee命令。
1. 同时输出到多个文件有时候,我们希望将命令的输出同时保存到多个文件中。
linux专题一之文件描述符、重定向、管道符、tee命令
linux专题⼀之⽂件描述符、重定向、管道符、tee命令本节讨论⼀下⼏个问题:1. ⽂件描述符。
2. 重定向。
3. 管道符4. tee的⽤法。
1. ⽂件描述符。
在linux系统中⼀切皆⽂件。
⽂件夹和设备都是⽂件。
如何⽤来区别不同的⽂件呢?这⾥的区别不是我们在windows下看到的后缀名不同来区别。
也不是我们在linux下⽤ls 命令看到的不同⽂件的列表。
这⾥的⽂件描述符主要讨论的是对⽂件操作的⼀个标识符。
⽆操作就⽆标识符。
⽐如两个进程同时在对同⼀个⽂件进⾏读操作。
如何区分这两个读操作呢?这就需要⽂件⽂件描述符来区别了。
每⼀次打开⼀个⽂件就形成了⼀个⽂件描述符,后打开的描述符⼀般都要⽐先打开的⽂件描述符⼤。
⽐如:我们可以man ⼀下 open函数。
看⼀下返回值:[root@xiaolyu ~]# man open也就是说⽂件描述符是⼀个整数。
当然了,系统默认最⼤是1024. 我们不妨⽤ulimit -n 来查看⼀下。
我们也可以查看⼀下:man socket ⼀下看⼀下效果:也就是说⽂件描述符可以通过多种途径来⽣成。
记住:只要对⽂件进⾏操作,就会返回⽂件描述符。
然后我们来看看系统⾃带的3个⽂件描述符。
这三个是最⼩的⽂件描述符,我们⾃⼰操作⽂件,返回的⽂件描述符最⼩都是从4开始的。
stdin 标准输⼊默认的设备是键盘⽂件描述符为:0命令将从标准输⼊⽂件中读取在执⾏过程中的需要的输⼊数据. -->数据来源于⽂件stdout 标准输出默认的设备是显⽰器⽂件描述符为:1命令执⾏后的输出结果,发送到标准输出⽂件. -->结果输出到⽂件stderr 标准错误默认的设备是显⽰器⽂件描述符为:2命令将执⾏期间的各种错误信息发送到标准错误⽂件 -->错误信息发送到⽂件标准输⼊,标准输出和标准错误默认使⽤键盘和显⽰器作为关联设备与操作系统进⾏交互完成最基本的输⼊,输出操作.我们不妨⽤man stdin 来看⼀下:[root@xiaolyu ~]# man stdin以上便是关于⽂件描述符。
Linux输入与输出重定向详解
Linux输⼊与输出重定向详解linux⽂件描述符:可以理解为linux跟踪打开⽂件,⽽分配的⼀个数字,这个数字有点类似c语⾔操作⽂件时候的句柄,通过句柄就可以实现⽂件的读写操作。
⽤户可以⾃定义⽂件描述符范围是:3-num,这个最⼤数字,跟⽤户的:ulimit –n 定义数字有关系,不能超过最⼤值。
linux启动后,会默认打开3个⽂件描述符,分别是:标准输⼊standard input 0,正确输出standard output 1,错误输出:error output 2以后打开⽂件后。
新增⽂件绑定描述符可以依次增加。
⼀条shell命令执⾏,都会继承⽗进程的⽂件描述符。
因此,所有运⾏的shell命令,都会有默认3个⽂件描述符。
对于任何⼀条linux 命令执⾏,它会是这样⼀个过程:⼀个命令执⾏了:先有⼀个输⼊:输⼊可以从键盘,也可以从⽂件得到命令执⾏完成:成功了,会把成功结果输出到屏幕:standard output默认是屏幕命令执⾏有错误:会把错误也输出到屏幕上⾯:standard error默认也是指的屏幕⽂件输⼊输出由追踪为⼀个给定的进程所有打开⽂件的整数句柄来完成。
这些数字值就是⽂件描述符。
最为⼈们所知的⽂件⽶描述符是stdin, stdout 和 stderr,⽂件描述符的数字分别是0,1和2。
这些数字和各⾃的设备是保留的。
⼀个命令执⾏前,先会准备好所有输⼊输出,默认分别绑定(stdin,stdout,stderr),如果这个时候出现错误,命令将终⽌,不会执⾏。
命令解析过程,可以参考:Linux Shell 通配符、元字符、转义符使⽤实例介绍这些默认的输出,输⼊都是linux系统内定的,我们在使⽤过程中,有时候并不希望执⾏结果输出到屏幕。
我想输出到⽂件或其它设备。
这个时候我们就需要进⾏输出重定向了。
linux shell下常⽤输⼊输出操作符是:1. 标准输⼊ (stdin) :代码为 0 ,使⽤ < 或 << ; /dev/stdin -> /proc/self/fd/0 0代表:/dev/stdin2. 标准输出 (stdout):代码为 1 ,使⽤ > 或 >> ; /dev/stdout -> /proc/self/fd/1 1代表:/dev/stdout3. 标准错误输出(stderr):代码为 2 ,使⽤ 2> 或 2>> ; /dev/stderr -> /proc/self/fd/2 2代表:/dev/stderr输出重定向:格式:command-line1 [1-n] > file或⽂件操作符或设备上⾯命令意思是:将⼀条命令执⾏结果(标准输出,或者错误输出,本来都要打印到屏幕上⾯的)重定向其它输出设备(⽂件,打开⽂件操作符,或打印机等等)1,2分别是标准输出,错误输出。
跟我学Linux编程-3-输入输出
Linux编程中的输入输出,如果只从C语言角度来看,可以说也没有什么特殊之处,本章节也并不打算花笔墨来介绍printf,scanf的用法。
但如果从Linux系统角度去看,又有不少有意思有东西,如输入输出重定向,管道,彩色字符显示等等,值得玩耍一翻,这才是接下来要我要介绍的重点。
Linux程序,运行后,通常会打开三个文件,其编号分别为0,1,2(我们称之为句柄号)。
其中0是标准输入,1是标准输出,2为错误输出。
我们来看个例子:程序什么也不做,一直sleep循环,以便于我们能够有时间查看它运行时的输入输出文件句柄。
执行:gcc inout.c -o io1编译完成后,我们执行程序:./io1再开一个新终端,执行:ps -a| grep io1会得到如下的信息:26065 pts/25 00:00:00 io1第一个整数是我们程序的进程编号(每次运行均有可能不一样),我们接下来的命令中需要用到它:ls /proc/26065/fd –l会显示这样的信息:lrwx------ 1 dxl dxl 64 3月30 09:58 0 -> /dev/pts/25lrwx------ 1 dxl dxl 64 3月30 09:58 1 -> /dev/pts/25lrwx------ 1 dxl dxl 64 3月30 09:55 2 -> /dev/pts/25显示的正是进程26065当前打开的文件句柄,共有3行,正是我上面所说的3个文件。
终端运行过程及结果Linux系统,程序打开的文件通常用一个整数句柄来表式。
我们可以调用close()函数来关闭它。
语法为:int close(int fd)其中,fd为文件句柄。
程序默认打开的标准输入输出文件句柄,也可以通过close来关闭。
我们接下来实验一下关闭0号文件会有什么现像发生:编译并执行:gcc inout.c -o io2./io2我们会意外发现,”Hello, world!”并没有在屏幕上输出!我们通过之前所说的方法,来查看io2的文件句柄打开情况:发现,1号文件确实是不存在了。
linux输入重定向用法
linux输入重定向用法摘要:1.重定向概念介绍2.标准输入输出重定向3.错误输出重定向4.文件重定向5.命令行参数重定向6.重定向在实际应用中的例子7.总结正文:Linux 中的输入重定向是指将命令的输入或输出从默认的位置(通常是终端)改为指定的位置。
这种灵活性使得用户能够更好地控制命令的执行过程。
以下是一些常见的重定向用法。
1.标准输入输出重定向将命令的输入或输出重定向到文件或设备,而不是终端。
例如:```cat > output.txt```这个命令将标准输出(stdout)重定向到名为output.txt 的文件中。
如果文件不存在,它会被创建。
如果文件已存在,则会覆盖现有内容。
2.错误输出重定向将命令的错误输出(stderr)重定向到文件或设备。
例如:```command > output.txt 2>&1```这个命令将标准输出和错误输出都重定向到名为output.txt 的文件中。
如果文件不存在,它会被创建。
如果文件已存在,则会覆盖现有内容。
3.文件重定向将命令的输入或输出重定向到指定文件。
例如:```command < input.txt```这个命令将名为input.txt 的文件作为命令的输入。
如果文件不存在,命令将无法执行。
4.命令行参数重定向将命令行参数重定向到文件或设备。
例如:```command arg1 arg2 > output.txt```这个命令将命令行参数arg1 和arg2 的值重定向到名为output.txt 的文件中。
这对于将命令的输出保存到文件中以便以后分析非常有用。
5.重定向在实际应用中的例子假设我们有一个名为“report.csv”的CSV 文件,我们想使用`awk`命令对文件中的数据进行处理,并将结果输出到一个新的CSV 文件中。
我们可以使用以下命令:```awk "{print $1, $2, $3}" report.csv > output.csv```这个命令将report.csv 文件作为输入,并使用awk 命令提取每行的第1、2 和3 列,然后将结果输出到名为output.csv 的新文件中。
linux重定向的几种写法
linux重定向的几种写法在Linux中,重定向是一种常用的操作,它允许我们将命令的输入或输出重定向到文件或其他设备。
以下是几种常见的重定向写法:1. 输出重定向:使用 `>` 符号将命令的标准输出重定向到文件,例如,`command > file.txt`。
这会将命令的输出覆盖写入到指定的文件中,如果文件不存在则会创建新文件。
使用 `>>` 符号将命令的标准输出追加到文件末尾,例如,`command >> file.txt`。
这会将命令的输出追加写入到指定的文件中,如果文件不存在则会创建新文件。
使用 `2>` 符号将命令的错误输出重定向到文件,例如,`command 2> error.txt`。
这会将命令的错误输出覆盖写入到指定的文件中,如果文件不存在则会创建新文件。
使用 `2>>` 符号将命令的错误输出追加到文件末尾,例如,`command 2>> error.txt`。
这会将命令的错误输出追加写入到指定的文件中,如果文件不存在则会创建新文件。
2. 输入重定向:使用 `<` 符号将文件内容作为命令的输入,例如,`command < file.txt`。
这会将文件的内容作为命令的输入。
使用 `<<` 符号创建一个输入结束符,例如,`command << EOF`。
这会允许你在命令行中输入多行内容,直到输入结束符为止。
3. 合并输出和错误:使用 `&>` 符号将命令的标准输出和错误输出合并重定向到文件,例如,`command &> output.txt`。
这会将命令的输出和错误输出都写入到指定的文件中,如果文件不存在则会创建新文件。
除了上述常见的重定向写法,还有其他一些特殊的重定向方式:`/dev/null`,可以将输出重定向到 `/dev/null`,它是一个特殊的设备文件,所有写入它的内容都会被丢弃,例如,`command >/dev/null`。
linux 标准输出重定向
linux 标准输出重定向Linux 标准输出重定向。
在Linux系统中,标准输出重定向是一种非常常见且有用的操作。
通过标准输出重定向,我们可以将程序的输出结果发送到指定的位置,而不是默认的标准输出设备(通常是显示器)。
这种操作对于日常的系统管理和脚本编写非常有用。
本文将介绍Linux系统中标准输出重定向的基本知识和常见用法。
1. 标准输出重定向符号。
在Linux系统中,标准输出重定向使用的符号是">"。
这个符号可以将程序的标准输出发送到指定的文件或设备。
例如,我们可以使用以下命令将ls命令的输出结果保存到一个文件中:```bash。
ls > file.txt。
```。
这样,ls命令的输出结果就会被重定向到file.txt文件中,而不是显示在屏幕上。
2. 追加重定向。
除了使用">"符号进行标准输出重定向外,我们还可以使用">>"符号进行追加重定向。
这个符号的作用是将程序的输出结果追加到指定的文件末尾。
例如,我们可以使用以下命令将当前目录下的所有文件名保存到一个文件中:```bash。
ls >> file.txt。
```。
这样,ls命令的输出结果会被追加到file.txt文件的末尾。
3. 标准错误重定向。
除了标准输出重定向外,Linux系统还提供了标准错误重定向的功能。
标准错误输出通常用于程序的错误信息提示。
我们可以使用"2>"符号将程序的标准错误输出重定向到指定的文件或设备。
例如,我们可以使用以下命令将错误信息保存到一个文件中:```bash。
command 2> error.txt。
```。
这样,command命令的错误信息就会被重定向到error.txt文件中。
4. 将标准输出和标准错误重定向到同一个文件。
有时候,我们希望将程序的标准输出和标准错误输出都重定向到同一个文件中,这样可以方便我们进行错误信息的查看和分析。
linux输入输出重定向及案例
linux输⼊输出重定向及案例重定向什么是重定向?将原本要输出在屏幕中的内容,重新定向输出到指定的⽂件或设备中。
** 为什么要使⽤重定向?**1.备份时,我们需要知道备份的结果2.屏幕上输出信息,⽐较重要的时候,我们想要保存下来3.定时任务,我们需要知道结果4.执⾏命令时,明知道会报错,我们会使⽤重定向,将结果放⼊ /dev/null5.执⾏命令时,正确结果和错误结果会同时输出,将正确结果输出到常规⽇志,将错误结果输出到错误⽇志重定向的分类标准输⼊标准输出名称⽂件描述符作⽤标准输⼊(stdin)0通常键盘(其他输⼊命令的终端设备)标准输出(stdout)1默认输出到屏幕错误输出(stderr)2默认输出到屏幕⽂件名(filename)3+-[root@localhost ~]# ll /dev/std*lrwxrwxrwx 1 root root 15 3⽉ 25 10:36 /dev/stderr -> /proc/self/fd/2lrwxrwxrwx 1 root root 15 3⽉ 25 10:36 /dev/stdin -> /proc/self/fd/0lrwxrwxrwx 1 root root 15 3⽉ 25 10:36 /dev/stdout -> /proc/self/fd/1[root@localhost ~]# ll /proc/121169/fd/总⽤量 0lrwx------ 1 root root 64 4⽉ 7 11:28 0 -> /dev/pts/3lrwx------ 1 root root 64 4⽉ 7 11:28 1 -> /dev/pts/3lrwx------ 1 root root 64 4⽉ 7 11:27 2 -> /dev/pts/3lr-x------ 1 root root 64 4⽉ 7 11:28 3 -> /var/log/messages输出重定向/dev/null/dev/pts/0/dev/pts/1/tmp/zls.txt/root/1.txt类型符号⽤途备注标准覆盖输出重定向1>将命令执⾏的正确结果默认输出的位置,修改为指定的⽂件或者终端(覆盖原有内容)通常'>'即可,1可以不写,默认就是1标准追加输出重定向>>将命令执⾏的正确结果,输出到指定⽂件的末尾(不覆盖原有内容)-错误覆盖输出重定向2>将命令执⾏的错误结果默认输出的位置,修改为指定的⽂件或者终端(覆盖原有内容)-错误追加输出重定向2>>将命令执⾏的错误结果,输出到指定⽂件的末尾(不覆盖原有内容)-标准输⼊重定向0<将命令中接收输⼊内容由默认的键盘,改为命令或者⽂件通常'<'即可0可以写也可以不写,默认0标准输⼊追加重定向0<<将命令中接收输⼊内容由默认的键盘,改为命令或者⽂件-# 标准覆盖输出重定向[root@localhost ~]# echo wxx>/tmp/1.txt[root@localhost ~]# cat /tmp/1.txtwxx[root@localhost ~]# echo 321>/tmp/2.txt[root@localhost ~]# cat /tmp/2.txt[root@localhost ~]# echo wxx1>/tmp/3.txt[root@localhost ~]# cat /tmp/3.txtwxx1**标准追加输出重定向**标准追加输出重定向[root@localhost ~]# echo 456 >> /var/log/messages[root@localhost ~]# echo 123 >> /var/log/messages**错误输出重定向**错误输出重定向[cdx@localhost ~]$ find /etc/ -type d**将标准输出和错误输出都输出到相同的⽂件中**将标准输出和错误输出都输出到相同的⽂件中[cdx@localhost ~]$ find /etc/ -type d > /tmp/100.txt 2>&1[cdx@localhost ~]$ find /etc/ -type d &> /tmp/101.txt**将错误输出,重定向到⿊洞**将错误输出,重定向到⿊洞[root@localhost ~]# ls / /ooo 2>/dev/null**脚本中使⽤重定向**脚本中使⽤重定向!/bin/bash. /etc/init.d/functionsread -p "请输⼊要检测的IP:" IPping -c1 -W1 $IP &>/dev/nullif [ ? -eq 0 ];then action "IP" /bin/true >> /tmp/IP_OK.txtelseaction "$IP" /bin/false >> /tmp/IP_FAILD.txtfi输⼊重定向[root@localhost ~]# mail -s "$(date +%F-%T)_test" 11111@ < /etc/passwd[root@localhost opt]# echo -e "111\n222\n333" > file1.txt[root@localhost opt]# cat file1.txt111222333[root@localhost opt]# echo '1111222233334444' > file2.txt[root@localhost opt]# cat >> 1.txt <<EOF> aaa> bbb> ccc> ddd> EOF[root@localhost opt]# cat >> 2.txt111222333444Ctrl + d 结束cat <<EOF+--------------------------+| vmware manager |+--------------------------+| by wxx |+--------------------------+| 1. Install KVM || 2. Install or Reset C6.5 || 3. Install or Reset C7.4 || 5. Instqll or Reset W7 || 6. Remove all || q. quit |+--------------------------+EOF[root@localhost opt]# cat <<EOF> 1.install mysql> 2.install nginx> 3.intsall php> 4.install tomcat> 5.install redis> EOF1.install mysql2.install nginx3.intsall php4.install tomcat5.install redis# 两条命令同时重定向[root@localhost opt]# (ls ; date) > 1.txt(while :; do date; sleep 2; done) &>date.txt &#如果不希望某些命令的执⾏对当前 shell 环境产⽣影响,请在subshell中执⾏[root@localhost ~]# (cd /boot; ls)管道技术管道操作符号:|,叫做管道符作⽤:将管道符左边命令的标准输出,交给管道符右边命令的标准输⼊来处理⽤法:cmd1|cmd2|cmd3| cmd4...# 取出passwd⽂件中,uid最⼤的前五个[root@localhost ~]# sort -nr -k 3 -t ':' /etc/passwd|head -5# 统计出passwd⽂件中,所有⽤户的shell种类[root@localhost ~]# awk -F: '{print $7}' /etc/passwd|sort |uniq|wc -l6[root@localhost ~]# hostname -I10.0.0.200[root@localhost ~]# ifconfig |awk 'NR==2{print $2}'10.0.0.200sedawkgrep组合:sed awkgrep awk10种⽅法,取IP# 取出磁盘已使⽤百分⽐[root@localhost ~]# df -h|awk '{print $5}'|awk -F '%' '{print $1}'已⽤912451# tee 和重定向的区别tee会将输出结果显⽰在屏幕上[root@zls ~]# date > date.txt[root@zls ~]# date |tee date.txt#xargs:将管道前⾯的结果当成管道后⾯命令的参数[root@localhost opt]# find /etc/ -name '*.conf'|xargs cp -t /tmp/⼗种⽅式取ip⼗种⽅法取ip[root@wzh ~]# ifconfig|awk 'NR==2 {print $2}'10.0.0.200[root@wzh ~]# ifconfig|sed -nr '2s#.*et (.*) ne.*#\1#gp'10.0.0.200[root@wzh ~]# ifconfig|grep -w 'broadcast'|cut -d ' ' -f1010.0.0.200[root@wzh ~]# ifconfig|sed -n '2p'|awk '{print $2}'10.0.0.200[root@wzh ~]# ifconfig|grep -w 'broadcast'|sed -r 's#.*et (.*) ne.*#\1#g'10.0.0.200[root@wzh ~]# ifconfig |head -2|tail -1|cut -d ' ' -f1010.0.0.200[root@wzh ~]# ifconfig|grep -w 'broadcast'|cut -c 14-2410.0.0.200[root@wzh ~]# ifconfig|awk 'NR==2'|cut -d 't' -f2|cut -d 'n' -f110.0.0.200[root@wzh ~]# ifconfig|sed -n '2p'|grep -o '[0.-9]*'|head -110.0.0.200[root@wzh ~]# ifconfig|sed -n '2p'|cut -d ' ' -f1010.0.0.200练习题01.复制/etc/passwd⽂件到当前⽬录下,把⽂件中的:替换成#,不能使⽤sed和vim命令。
linux输入重定向用法
linux输入重定向用法
在Linux中,输入重定向用于改变命令的输入源。
通过使用输入重定向,您可以将命令的输入从键盘改为文件或其他命令的输出。
输入重定向的语法如下:
```bash
command<file
```
其中,`command`是要执行的实际命令,`file`是要用作输入的文件。
例如,如果您有一个名为`input.txt`的文件,并希望使用该文件作为`grep`命令的输入,则可以使用以下命令:
```bash
grep"pattern"<input.txt
```
这将以`input.txt`文件中的内容作为输入,并使用`grep`命令搜索匹配的行。
除了文件之外,还可以使用管道将一个命令的输出作为另一个命令的输入。
例如:
```bash
command1|command2
```
这会将`command1`的输出作为`command2`的输入。
例
如,要使用`grep`命令搜索包含特定模式的行,并将结果传递给`sort`命令进行排序,可以使用以下命令:
```bash
grep"pattern"file.txt|sort
```
这将以`file.txt`文件中的内容作为输入,使用`grep`命令搜索匹配的行,并将结果传递给`sort`命令进行排序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.通过dup2()系统调用把STDIN重定向到fd_in,把STDOUT重定向到fd_out(注意,重定向的影响范围是整个子进程);
4.通过system()系统调用运行shell命令sort
lrwx------ 1 dagang dagang 64 Feb 27 13:41 1 -> /dev/pts/3
lrwx------ 1 dagang dagang 64 Feb 27 13:41 2 -> /dev/pts/3
上面我们启动了两个进程5583和5584,通过查看/proc//fd,我们看到进程5583的STDOUT和5584的STDIN被重定向到了pipe:[246469],这样就达到了连接两个进程标准I/O的目的。
下面我们通过strace命令跟踪一下echo命令的系统调用:
dagang@ubuntu12:~$ strace echo hello 2>&1 >/dev/null | grep write
write(1, "hello\n", 6) = 6
我们可以看到write(1, "hello\n", 6)这样一个系统调用,它的第一个参数1就是代表的STDOUT的FD,这说明对于echo程序,它只管(通过标准I/O函数从STDOUT)向FD 1写入,而不关心它们FD 1到底对应的是哪个文件。
Shell正是通过I/O重定向和管道这种特殊的文件把多个程序的STDIN和STDOUT串联在一起组成更复杂功能的,下面是Shell中通过管道的示意图:
下面我们用一个实际的例子来体验一下:
dagang@ubuntu12:~$ sleep 30 | sleep 40 &
[1] 5584
dagang@ubuntu12:~$ pgrep -l sleep
通过上面的例子我们就了解最基本的I/O重定向的实现方法,接下来,你能否根据这些知识进一步实现出Shell的管道特性呢?
总结
本文介绍了Linux系统I/O重定向的原理和实现方式。原理方法最重要的是理解文件描述符和文件描述符表的概念,以及标准I/O所对应的特殊FD;实现方面主要是了解dup2()系统调用的功能和用法。最后需要注意的是dup2()不仅可以用来对标准I/O重定向,对任何FD都是可以的,这是习惯使用Shell进行标准I/O重定向的朋友容易忽略的。
这里我们通过一个实际的问题来说明它的使用方法:
编写一个C程序,通过调用sort这个Shell命令进行排序,要求把in.txt和out.txt分别重定向到sort的STDIN,STDOUT。
参考实现:
int main() {
int pid = 0;
// fork a worker process
if (pid = fork()) {
dup2()系统调用
上面介绍了文件描述符表和I/O重定向的原理,那么在Linux系统中如何通过C程序实现I/O重定向呢?主要用到了dup2()这个系统调用,man中关于dup2是这样说的:
int dup2(int oldfd, int newfd);
dup2() create a copy of the file descriptor oldfd. After a successful return from dup() or dup2(), the old and new file descriptors may be used interchangeably. They refer to the same open file description (see open(2)) and thus share file offset and file status flags; for example, if the file offset is modified by using lseek(2) on one of the descriptors, the offset is also changed for the other.
int fd_out = open("out.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd_in > 0 && fd_out > 0) {
// redirect STDIN/STDOUT for this process
// wait for completion of the child process
int status;
waitpid(pid, &status, 0);
}
else {
// open input and output files
int fd_in = open("in.txt", O_RDONLY);
5583 sleep
5584 sleep
dagang@ubuntu12:~$ ll /proc/5583/fd
total 0
lrwx------ 1 dagang dagang 64 Feb 27 13:41 0 -> /dev/pts/3
l-wx------ 1 dagang dagang 64 Feb 27 13:41 1 -> pipe:[246469]
所谓的I/O重定向也就是让已创建的FD指向其他文件。比如,下面是对STDOUT重定向到testfile.txt前后内核文件描述符表变化的示意图
重定向前:
重定向后:
在I/O重定向的过程中,不变的是FD0/1/2代表STDIN/STDOUT/STDERR,变化的是文件描述符表中FD 0/1/2对应的具体文件,应用程序只关心前者。本质上这和接口的原理是相通的,通过一个间接层把功能的使用者和提供者解耦。
dup2(fd_in, 0);
dup2(fd_out, 1);
// call shell command
system("sort");
close(fd_in);
close(fd_out);
}
else {
// ... error handling
}
}
return 0;
}
上面的主要步骤包括:
1.首先fork一个子进程,后续步骤都在子进程中完成,父进程通过waitpid()系统调用等待子进程结束;
lrwx------ 1 dagang dagang 64 Feb 27 13:41 2 -> /dev/pts/3
dagang@ubuntu12:~$ ll /proc/5584/fd
total 0
lr-x------ 1 dagang dagang 64 Feb 27 13:41 0 -> pipe:[246469]
下面本文就以Linux系统为具体例子,介绍I/O重定向的原理和实现(文中实验环境为Ubuntu 12.04,内核版本3.2.0-59)。
文件描述符表
理解I/O重定向的原理需要从Linux内核为进程所维护的关键数据结构入手。对Linux进程来讲,每个打开的文件都是通过文件描述符(File Descriptor)来标识的,内核为每个进程维护了一个文件描述符表,这个表以FD为索引,再进一步指向文件的详细信息。在进程创建时,内核为进程默认创建了0、1、2三个特殊的FD,这就是STDIN、STDOUT和STDERR,如下图所示意:
Linux I/O重定向的原理和实现
在Unix系统中,每个进程都有STDIN、STDOUT和STDERR这3种标准I/O,它们是程序最通用的输入输出方式。几乎所有语言都有相应的标准I/O函数,比如,C语言可以通过scanf从终端输入字符,通过printf向终端输出字符。熟悉Shell的朋友都知道,我们可以方便地对Shell命令进行I/O重定向,比如find -name "*.java" >testfile.txt把当前目录下的Java文件列表重定向到testfile.txt。多数情况下,我们只需要了解I/O重定向的使用就够了,但是如果要编程实现类似Shell的I/O重定向以及管道功能,那么就需要清楚它的原理和实现。