玩转linux文件描述符和重定向,玩转Linux文件描述符和重定向

本文介绍linux中文件描述符与重定向的相关知识,文件描述符是与文件输入、输出相关联的整数,它们用来跟踪已打开的文件。有需要的朋友参考下。

原文出处:

linux下的文件描述符是与文件输入、输出相关联的整数。它们用来跟踪已打开的文件。

最常见的文件描述符是stdin、stdout和stderr.我们可以将某个文件描述符的内容重定向到另一个文件描述符中。

下面给出一些对文件描述符进行操作和重定向的例子。

1.5.1 预备知识

我们在编写脚本时会频繁使用标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。

通过内容过滤将输出重定向到文件是我们从事的基础任务之一。

当命令输出文本时,这些输出文本有可能是错误信息,也可能是正常的(非错误的)输出信息。

单靠查看输出的文本本身,  我们无法区分哪些是正常的输出文本,哪些是错误文本。不过,我们可以通过文件描述符来解决这个问题,将那些与特定描述符关联的文本提取出来。

文件描述符是与一个打开的文件或数据流相关联的整数。文件描述符0、1以及2是系统预留的。

0——stdin(标准输入)

1——stdout(标准输出)

2——stderr(标准错误)

1.5.2  实战演练

将输出文本重定向或保存到一个文件中:

$echo"This is a sample text 1">temp.txt

这种方法通过截取文件的方式,将输出文本存储到文件temp.txt中,也就是说在把echo命令的输出写入文件之前,temp.txt中的内容首先会被清空。

接下来,再看另一个例子:

$echo "this is sample text 2" >>temp.txt

这种方法会将文本追加到目标文件中。

>和>>并不相同。尽管这两个操作符都可以将文本重定向到文件,但是前者会先清空文件,再写入内容;而后者会将内容追加到现有文件的尾部。

可以用下面的方法查看文件内容:

$cat temp.txt

this is sample text 1

this is sample text 2

在中,当使用重定向操作符时,重定向的内容不会出现在终端,而是直接被导入文件。重定向操作符默认使用标准输出。如果想使用特定的文件描述符,你必须将描述符置于操作符之前。

>等同于1>;对于>>来说,情况也类似(即>>等同于1>>)。

来看看什么是标准错误以及如何对它重定向。当命令输出错误信息时,stderr信息就会被打印出来。考虑下面的例子:

$ Is +

Is:cannot access +:No such file or directory

这里,+是一个非法参数,因些将返回错误信息。

[ 成功和不成功的命令

当一个命令发生错误并退回时,它会返回一个非0的退出状态;而当命令成功完成后,它会返回数字0。退出状态可以从特殊变量$? 中获得(在命令执行语句之后立刻运行echo$?,就可以打印出退出状态)。]

将stderr文本打印到屏幕上,而不是文件中。

$ Is+>out.txt

Is:cannot access+:No such file or directory

然而在下面的命令中,stdout没有任何输出,因为错误已经重定向到out.txt中去了。

$ Is +2> out.txt # 正常运行

你可以将stderr单独重定向到一个文件,将stdout重定向到另一个文件:

$ cmd 2>stderr.txt 1>stdout.txt

还可以利用下面的方法将stderr转换成stdout,使得stderr和stdout都被重定向到同一个文件中:

$ cmd 2>&1 output.txt

或者采用下列方法:

$ cmd&> output.txt

有时候,在输出中可能包含一些不必要的信息(比如除错信息)。如果你不想让终端中充斥着有关stderr的繁枝末节,那么你可以将stderr的输出重定向到/dev/null, 保证一切都会被清除得干干净净。假设我们有三个文件,分别是a1、a2、a3。但是普通用户对a1没有“读一写一执行”权限。如果你需要打印文件名以a起始的所有文件的内容,你可以使用。

设置一些测试文件:

$ echo a1 >a1

$ cp a1 a2;cp a2 a3;

$ chmod 000 a1 #清除所有权限

尽管可以使用通配符(a*)显示所有的文件内容,但是系统会显示一个出错信息,因为对文件a1没有可读权限。

$ cat a*

cat:a1 permission denied

a1

a1

其中,cat:a1:permission denied 属于stderr。我们可以将stderr信息重定向到一个文件中,而stdout 仍然保持不变。考虑如下代码:

$ cat a* 2>err.txt #stderr被重定向到err.txt

a1

a1

$ cat err.txt

cat:a1:permission denied

观察下面的代码:

$ some_command 2>/dev/null

本节是 的内容,欢迎大家继续阅读。

在这个示例中,来自stderr的输出被丢到文件/dev/null中。/dev/null是一个特殊的设备文件,这个文件接收到的任何数据都会被丢弃。

因此,null设备通常也被为位桶(bit bucket)或黑洞。

当对stderr或stdout进行重定向时,重定向的文本将传入文件。

因为文本已经被重定向到文件中,也就没剩下什么东西可以通过管道(|)传给接下来的命令,而这些命令是通过stdin来接收文本的。

但是有一个巧妙的方法可以一方面将数据重定向到文件,另一方面还可以提供一些重定向数据的副本作为后续命令的stdin。

这一切都可以使用tee来实现。

举个例子:要在终端中打印stdout,同时将它重定向到一个文件中,那么可以这样使用tee:

command | tee FILE1 FILE2

在下面的代码中,tee命令接收到来自stdin的数据。它将stdout的一份副写入文件out.txt,同时将别一份副本作为后续命令的stdin。命令cat -n将从stdin中接收到的每一行数据前加上行号并写入stdout:

$ cat a*| tee out.txt| cat -n

cat: a1: permission denied

1 a1

2 a1

查看out.txt 的内容:

$ cat out.txt

a1

a1

注意,cat:a1:permission denied并没有在任何文件内容中出现。这是因为这些信息属于stderr,而tee只能从stdin中进行读取。

默认情况下,tee命令会将文件覆盖,但是提供了一个-a选项,可以用于追加内容。例如:

$ cat a*| tee -a out.txt| cat -n.

带有参数的命令可以写成:command FILE1 FILE2依次类推,或者简简单单地用command FILE。

我们可以使用stdin作为命令参数。只需要将-作为命令的文件名参数即可:

$ cmd1 |cmd2 |cmd -

例如:

$ echo who is this | tee-

who is this

who is this

或者我们也可以将/dev/stdin作为输出文件名来使用stdin。

类似的,使用/dev/stderr代表标准错误,/dev/stdout代表标准输出。这些特殊的设备文件分别对应stdin、stderr和stdout。

补充内容:

从stdin读取输入的命令能以多种方式接收数据。另外,还可以用cat和管道来制定我们自己的文件描述符,例如:

$ cat file | cmd

$ cmd1 | cmd2

1.将文件重定向到命令

借助重定向,我们可以像使用stdin那样从文件中读取数据:

$ cmd

2.重定向脚本内部的文本块

有时候,需要对文本块(多行文本)像标准输入一样进行重定向。考虑一个特殊情况:源文本就位于shell脚本中。

来看下面这段吧,向log文件中写入头部数据,可以按照下面的方法完成:

#!/bin/bash

cat

LOG FILE HEADER

This is a test log file

Function:System statistics

EOF

在cat

$ cat log.txt

LOG FILE HEADER

This is a test log file

Function:System statistics

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533177.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux哪个指令可以设定使用者的密码,linux期末考试练习题 2

一、单项选择题1、下面不是对Linux操作系统特点描述的是()A、良好的可移植性B、单用户C、多用户D、设备独立性2、查看创建目录命令mkdir的帮助文档可以使用()A、mkdir -hB、man mkdirC、help mkdirD、info mkdir3、用标准的输出重定向(>)像”>file01”能使文件file01的数…

linux脚本格式模板,Linux Shell 常见的命令行格式简明总结

#在后台执行 cmd 指令cmd &#命令序列. 在同一行执行多个命令cmd1 ; cmd2#在当前 shell 中以一组的形式执行多个命令{ cmd1 ; cmd2 ; }#在子 shell 中以一组的形式执行多个命令(cmd1 ; cmd2)#管道. 以 cmd1 的执行输出作为 cmd2 的输入cmd1 | cmd2#命令替换. 以 cmd2 的执行…

linux怎么用命令打开wine,Linux系统运维:10分钟教你如何使用Wine在Linux下玩魔兽世界...

本文主要向大家介绍了Linux系统运维的如何使用Wine在Linux下玩魔兽世界,通过具体的步骤向大家展现,希望对大家学习Linux系统运维有所帮助。目标:在 Linux 中运行魔兽世界发行版:适用于几乎所有的 Linux 发行版。要求:具…

linux中如何查看某个端口是否被占用,LINUX中如何查看某个端口是否被占用

之前查询端口是否被占用一直搞不明白,问了好多人,终于搞懂了,现在总结下:1.netstat -anp |grep 端口号如下,我以3306为例,netstat -anp |grep 3306(此处备注下,我是以普通用户操作&#…

linux实现自己的write函数,Linux 内核源码阅读 - write 系统调用的实现

最近在看write系统调用的实现,虽然还有一下细节不是很清楚,但是大致的实现机理还是有一定的理解了。总结如下:这里假设最普通的情况,不考虑Direct IO 的情况。从全家的高度看,要往一个文件中写入内容,需要一…

linux7.0使用教程,CentOS7.0使用手册精编.pdf

CentOS7.0 手册第一部分:显卡驱动安装篇 (针对单显卡而言)或许CentOS7.0 版本是遇到的装显卡驱动最烦的一个,相比Ubuntu 、CentOS7.0 之前版本(如:CentOS6.5、CentOS6.4 )而言,操作步骤如下:由于笔者我的显卡是华硕圣骑…

linux中s权限大小写的区别,Linux中的权限

1.文件与目录权限1)UID与GIDUIDUID是一个数值,是Linux系统中唯一的用户标识,用于区别不同的用户。在系统内部管理进程和文件保护时使用UID字段。在Linux系统中,注册名和UID都可以用于标识用户,只不过对于系统来说UID更为重要&…

linux中shell自动对齐代码,linux – Shell编程 – 如何printf像表一样对齐我的输出?...

如何printf像表格一样对齐我的输出?Title AuthorBaokyBook Baoky2Use basename commandUse basename command .. Baoky我的部分代码是这样的titlelength${#title};首先我获得标题长度,然后我就像这样打印titlespaceexpr 60 - titlelength;printf "%s %${titles…

linux的安装组和管理组的区别吗,Linux用户和组管理

Linux用户和组管理安装上下文:进程以其发起者的身份运行;进程对文件的访问权限,取决于发起此进程的用户的权限;系统用户:为了能够让那后台进程或服务类进程以非管理员的身份运行,通常需要为此创建多个普通用…

在linux下vcd光盘提取,linux下抓取Vcd的视频文件[Linux安全]

赞助商链接本文“linux下抓取Vcd的视频文件[Linux安全]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:LP的瑜伽碟需…

Linux清mysql磁盘,mysql与linux ~ 磁盘分析与调优

一 简介 谈谈磁盘IO的问题二 目的:如何进行IO性能问题的排查二 linux角度一 机械硬盘基本定义寻道时间,表示磁头在不同磁道之间移动的时间(最耗时)。旋转延迟,表示在磁道找到时,中轴带动盘面旋转到合适的扇区开头处。传输时间,表…

arm与linux的些许问题,《ARM与Linux些许问题》第一章:ARM工作模式

早期的ARM核有状态(ARM或Thumb)切换(通过BX等指令修改CPSR寄存器(当前程序状态寄存器,存放条件码标志,中断禁止位,当前处理器模式以及其他状态和控制信息)中T的控制位完成程序状态的切换),现在ARM都只使用Thumb状态了。所以&#…

c语言给定一个字符串匹配,使用C语言解决字符串匹配问题的方法

最常想到的方法是使用KMP字符串匹配算法&#xff1a;#include #include #include int get_nextval(char *pattern,int next[]){//get the next value of the patternint i 0,j -1;next[0] -1;int patlen strlen(pattern);while ( i < patlen - 1){if ( j -1 || pattern…

c语言比较大小 谁大选谁,C语言比较优先级

满意答案wanggq2222018.03.14采纳率&#xff1a;42% 等级&#xff1a;7已帮助&#xff1a;57人#pragma once#include#include#include #includeusing namespace std;typedef struct SymKeyVal{string key;int val;};static SymKeyVal KeyValTable[]{{"",0},{"…

c语言ip地址吗,C语言:判断IP地址是否合法

int is_valid_ip(const char *ip){int section 0; //每一节的十进制值int dot 0; //几个点分隔符int last -1; //每一节中上一个字符while(*ip){if(*ip .){dot;if(dot > 3){return 0;}if(section > 0 && section <255){section 0;}else{retur…

10100的素数c语言程序,C语言基础题目及代码.doc

/*读入一个自然数n&#xff0c;计算其各位数字之和&#xff0c;用汉语拼音写出和的每一位数字。输入格式&#xff1a;每个测试输入包含1个测试用例&#xff0c;即给出自然数n的值。这里保证n小于10100。输出格式&#xff1a;在一行内输出n的各位数字之和的每一位&#xff0c;拼…

c语言闰年的判断条件DS1302,DS1302驱动程序(平年和闰年天数自动调整)

/*********************************************************************************1.本程序能够显示年&#xff0c;月&#xff0c;日&#xff0c;时&#xff0c;分&#xff0c;秒&#xff0c;星期七个参数.2.时间和日期可调。可分别完成年&#xff0c;月&#xff0c;日&am…

android 图片切割代码,Android用clip剪切图像资源

使用clip剪切图像资源可以做进度条&#xff0c;图像慢慢展开的效果&#xff0c;他使用以下几个属性来控制效果&#xff1a;android:drawable&#xff1a;指定要剪切的原图像。android:clipOrientation&#xff1a;截取的方向。可取的值&#xff1a;horizontal和vertical。分别表…

android gradle错误,Android studio gradle错误与顶级异常

我最近更新了我的Android Studio,从那以后我的项目没有构建...我得到错误,如下面的错误:Error Code:1Output:UNEXPECTED TOP-LEVEL EXCEPTION:com.android.dx.cf.iface.ParseException:class name (org/pervasivesystems/mobilehealth/activities/AppSettingsActivity$AppSetti…

Android中列表动态删除item,如何删除Android ExpandableListView中某个group item的child item?...

自定义了一个expandablelistview 想要删除其中的子项list使用remove方法把list中的指定项删除了11-09 21:04:20.585: I/MainActivity(13557): childData[{child_textsecond}, {child_textthird}]但是在expandablelistview界面显示中&#xff0c;并没有变化,并且还有list溢出报错…