余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

Linux输入输出重定向,我的代码实证和深度理解

xiyangw 2023-05-14 11:50 14 浏览 0 评论

事先申明,本文在理解Linux输入输出重定向方面,是有点干货的。有别于一般泛泛然的讲解,内容以源码为证,讲的比较实在。当然,如果你对“输入输出重定向”这个概念上都不知道,还是欢迎移步看我的其它文章吧。

Linux输入输出重定向,我的代码实证和深度理解

Linux的shell命令的高级操作,主要有:

  • 输出重定向,操作符是:>、>>
  • 输入重定向,操作符是:<
  • 管道操作,操作符是(|)

为了从原理上说明管道操作,我们首先得了解文件描述符。关于文件描述符的背景知识,请参看我发过的笔记《我当年的Linux系统编程笔记-文件描述符》,这里不再复述。这里只对文件描述符、标准文件描述符的概念进行一个大致的讲解。

1 文件描述符

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。在windows中,内核记录应用打开的对象,就是handle句柄,也是一个整数值,两者有相似之处。

在Linux中,在编写脚本的时候会频繁使用标准输入( stdin)、标准输出( stdout)和标准错误( stderr)。通过内容过滤将输出重定向到文件是我们平日里的基本任务之一。文件描述符是与某个打开的文件或数据流相关联的整数。文件描述符0、 1以及2是系统预留的,相当于每个进程的全局变量,它们被称为标准文件描述符。

2 Shell 输入重定向"<"的基本概念


命令语法:command < file

对该命令的解释是:将输入重定向到 file。

进一步的解释是:本来需要从键盘stdin获取输入的命令,会转移到文件file读取内容

3 Shell 输入重定向"<"命令的例子

$ cat input.txt

Line1:This is a sample

Line2:123456abc

Line3:Just file!

$ wc -l < input.txt

3 (wc命令统计的行数)

注意:如果命令不能从标准设备(stdin)读取数据,这个命令就不能做输入重定向。举例如下:

$ cat wantToEcho.txt

Line1:This is wantToEcho file

$ echo < wantToEcho.txt

命令“ echo < wantToEcho.txt”不会显示任何数据到命令行上。因为echo命令没有从标准设备(stdin)读取数据的能力,所以不会执行成功。

4 代码实证理解

从程序的观点出发,输入重定向命令“command < file”中,Linux管道机制将操作符<右边的file打开后,输出到stdin。如果command具有从stdin读取数据的动作,就正好接收处理。不符合这种情况的命令,不可以用到输入重定向中来。

怎么证实这个观点呢?还是下面的代码"in-redirect.c"验证最为直接。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUF_LEN 1024
int main(void)
{
    char read_buf[BUF_LEN +1];
    ssize_t len_read;
    len_read = read(0,read_buf,BUF_LEN);  //这个0,就是stdin

    if ( len_read < 0 )
    {
        perror("perror:file read error ");
        exit(1);
    }

    read_buf[len_read]=0x0;
    printf("read stdin:%s\n",read_buf);
    return 0;
}

编译:gcc in-redirect.c -o in-redirect.out

下面是验证过程:

$ ./in-redirect.out

123456abc789 (此处手工输入)

read stdin:123456abc789 

$ cat input.txt 下面一行是input.txt文件中的内容

Line1:This is a sample

$ ./in-redirect.out < input.txt

read stdin:Line1:This is a sample

in-redirect.out这个程序,会从stdin中读取内容,通过“<”把它重定向成向input.txt中读数据了。因为有了源码示例,所以这个对“<”的理解比较通透

为什么上面的代码“read(0,...);”之前,不用先open打开呢?

这是因为“标准文件描述符”有别于其它“文件描述符”,它们是进程创建就默认打开着的,不用open。你可以理解为0、1、2这三个文件描述符是进程的全局变量。既然是全局变量,拿来就用,可以read,也可以write,就不用open了,因为进程在创建之初,就相当于为你open过了。

5 输入重定向(<)和输出重定向(>、>>)的区别

从系统编程的角度来理解,输出重定向"command > file"就是:command命令输出数据,向stdout或stderr输出(write)数据,Linux Shell把这些数据重新定向(open)输出(write)到file文件中。也就是说:输出重定向就是对stdout或stderr进行重定向

而输入重定向“command < file”,则是把Linux Shell把文件打开(open),writestdio中去,然后command来读取(readstdio的数据并进行处理。也就是说:输入重定向,就是对stdin进行重定向

6 输入重定向和输出重定向混用

其实,只要符合输入输出重定向的语法,内部再符合标准输出输出的stdout、stdin、stderr的读read写write要求,都可以组合使用,不管命令有多么长

比如上面的命令:wc -l < input.txt (统计input.txt的行数),如果我们想把它再输出到一个计数文件cout.txt中,可以这样做

$ cat input.txt

Line1:This is a sample

Line2:123456abc

Line3:Just file!

$ wc -l < input.txt > cout.txt

$ cat cout.txt

3

这两个命令和执行结果的说明:

wc -l < input.txt > cout.txt :wc命令本来要从stdin中读取数据,结果被输入重定向了(<),变成从文件input.txt中去读数据了。输出的结果本来要输出到stdout屏幕,结果被输出重定向了(>),变成了输出到文件cout.txt中了。

(这里是虎哥,撸代码板子20载,目前文笔尚差,但均是有感而发。技术一般,还需提高。请关注我,看看数码,聊聊软件,侃侃职场,相互学习,有项目一起发财!)

相关推荐

辞旧迎新,新手使用Containerd时的几点须知

相信大家在2020年岁末都被Kubernetes即将抛弃Docker的消息刷屏了。事实上作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使...

分布式日志系统ELK+skywalking分布式链路完整搭建流程

开头在分布式系统中,日志跟踪是一件很令程序员头疼的问题,在遇到生产问题时,如果是多节点需要打开多节点服务器去跟踪问题,如果下游也是多节点且调用多个服务,那就更麻烦,再者,如果没有分布式链路,在生产日志...

Linux用户和用户组管理

1、用户账户概述-AAA介绍AAA指的是Authentication、Authorization、Accounting,即认证、授权和审计。?认证:验证用户是否可以获得权限,是3A的第一步,即验证身份...

linux查看最后N条日志

其实很简单,只需要用到tail这个命令tail-100catalina.out输入以上命令,就能列出catalina.out的最后100行。...

解决linux系统日志时间错误的问题

今天发现一台虚拟机下的系统日志:/var/log/messages,文件时间戳不对,跟正常时间差了12个小时。按网上说的执行了servicersyslogrestart重启syslog服务,还是不...

全程软件测试(六十二):软件测试工作如何运用Linux—读书笔记

从事过软件测试的小伙们就会明白会使用Linux是多么重要的一件事,工作时需要用到,面试时会被问到,简历中需要写到。对于软件测试人员来说,不需要你多么熟练使用Linux所有命令,也不需要你对Linux...

Linux运维之为Nginx添加错误日志(error_log)配置

Nginx错误日志信息介绍配置记录Nginx的错误信息是调试Nginx服务的重要手段,属于核心功能模块(nginx_core_module)的参数,该参数名字为error_log,可以放在不同的虚机主...

Linux使用swatchdog实时监控日志文件的变化

1.前言本教程主要讲解在Linux系统中如何使用swatchdog实时监控日志文件的变化。swatchdog(SimpleWATCHDOG)是一个简单的Perl脚本,用于监视类Unix系统(比如...

syslog服务详解

背景:需求来自于一个客户想将服务器的日志转发到自己的日志服务器上,所以希望我们能提供这个转发的功能,同时还要满足syslog协议。1什么是syslog服务1.1syslog标准协议如下图这里的fa...

linux日志文件的管理、备份及日志服务器的搭建

日志文件存放目录:/var/log[root@xinglog]#cd/var/log[root@xinglog]#lsmessages:系统日志secure:登录日志———————————...

运维之日志管理简介

日志简介在运维过程中,日志是必不可少的东西,通过日志可以快速发现问题所在。日志分类日志分类,对不同的日志进行不同维度的分析。操作系统日志操作系统是基础,应用都是在其之上;操作系统日志的分析,可以反馈出...

Apache Log4j 爆核弹级漏洞,Spring Boot 默认日志框架就能完美躲过

这两天沸沸扬扬的Log4j2漏洞门事件炒得热火朝天:突发!ApacheLog4j2报核弹级漏洞。。赶紧修复!!|Java技术栈|Java|SpringBoot|Spring...

Linux服务器存在大量log日志,如何快速定位错误?

来源:blog.csdn.net/nan1996jiang/articlep/details/109550303针对大量log日志快速定位错误地方tail/head简单命令使用:附加针对大量log日志...

Linux中查看日志文件的正确姿势,求你别tail走天下了!

作为一个后端开发工程师,在Linux中查看查看文件内容是基本操作了。尤其是通常要分析日志文件排查问题,那么我们应该如何正确打开日志文件呢?对于我这种小菜鸡来说,第一反应就是cat,tail,vi(或...

分享几款常用的付费日志系统,献给迷茫的你!

概述在前一篇文章中,我们分享了几款免费的日志服务器。他们各有各的特点,但是大家有不同的需求,有时免费的服务器不能满足大家的需要,下面推荐几款付费的日志服务器。1.Nagios日志服务器Nagio...

取消回复欢迎 发表评论: