【Linux系列】 Bash 重定向中 file 21 和 21 file 的区别

news/2024/10/5 10:21:00/文章来源:https://www.cnblogs.com/o-O-oO/p/18274814

一、 写在前面

在 Bash 脚本和命令行操作中,输出重定向是一项基本且强大的功能。
它允许用户控制命令的输出流,将数据从一个地方转移到另一个地方,实现更加灵活和高效的工作流程。
本文旨在记录 Bash 中几种常见的输出重定向方法,包括:

> file

>file 2>&1 vs 2>&1 >file

| (pipe)

二、 基本概念

文件描述符(File Descriptor, FD)是 Unix 和 Unix-like 操作系统中的基本概念,用于表示一个进程打开的文件、管道、套接字或其他输入/输出资源。每个进程都有一个文件描述符表,管理其所有打开的文件。其中,对于系统管理员来说,STDIN、STDOUT 和 STDERR 这几个术语应该很熟悉,对应于程序内的三个文件描述符:0、1 和 2。

STDIN、STDOUT 和 STDERR 是三个标准的输入输出流,是操作系统为进程提供的默认输入和输出机制:

标准输入(STDIN):

    描述:STDIN 是标准输入流,通常从键盘输入文件描述符:0默认来源:键盘作用:用于从用户或其他进程读取输入数据

标准输出(STDOUT):

    描述:STDOUT 是标准输出流,通常显示在屏幕上文件描述符:1默认目标:终端(屏幕)作用:用于向用户或其他进程输出数据示例:echo "Hello, World!"在这个示例中,echo 命令将字符串输出到 STDOUT,默认情况下显示在屏幕上。

标准错误(STDERR):

    描述:STDERR 是标准错误流,专门用于输出错误消息;文件描述符:2默认目标:终端(屏幕)作用:用于输出错误和诊断信息,不会与正常输出混淆;示例:ls non_existent_file在这个示例中,ls 命令会尝试列出一个不存在的文件,并将错误消息输出到 STDERR。

实际上,在程序中执行文件操作时,会生成新的文件描述符,通常从 3、4、5 开始,依次类推。内置的 0、1、2 最初并不指向任何文件,而是指向 /dev/tty。这意味着应用程序可以通过 STDIN 从 tty 向程序发送数据,反之亦然,它可以通过 STDOUT 和 STDERR 向 /dev/tty 输出不同类型的输出。

以下面脚本为例:test.sh

#!/bin/bash
echo "Hello stdout"
echo "Hello stderr" 1>&2

向 STDOUT 输出 "Hello stdout",向 STDERR 输出 "Hello stderr"。

执行脚本如下:

因此,在默认条件下,两者的关系如下:

三、 输出重定向

以下是几种常见的输出重定向方法及其用途:

> file

将标准输出(STDOUT)重定向到文件。如果文件不存在,则创建该文件,如果文件存在,则覆盖该文件的内容。

echo "Hello, World!" > output.txt

这个命令将字符串 "Hello, World!" 输出到 output.txt 文件中。

>file 2>&12>&1 >file

"> file" 和 "2>&1" 是重定向的语法,用于分别控制标准输出(stdout)和标准错误输出(stderr)。

理解 ">file 2>&1" 和 "2>&1 >file" 需要理解命令重定向的顺序以及它们各自的作用。

 ">file 2>&1" 命令解释:"> file":将标准输出重定向到 file 文件;"2>&1":将标准错误输出重定向到标准输出(在这时,标准输出已经被重定向到 file);

因此,所有的输出(标准输出和标准错误输出)都会被重定向到 file 文件中。

"2>&1 >file" 命令解释:"2>&1":将标准错误输出重定向到标准输出(在这时,标准输出还指向终端);"> file":将标准输出重定向到 file 文件;

在这个顺序中,标准错误输出仍然重定向到原始的标准输出(终端),而标准输出被重定向到 file 文件。
结果是:

    标准输出被重定向到 file 文件;标准错误输出仍然输出到终端;

假设命令 ls 629 会产生一个标准错误输出。

使用 > file 2>&1

在 output.txt 文件中,你会看到标准错误信息:

使用 2>&1 > file

在 output.txt 文件中将会是空的,因为标准输出重定向到文件,而标准错误输出仍然显示在终端:

    >file 2>&1:将标准输出和标准错误都重定向到 file;2>&1 >file:将标准输出重定向到 file,标准错误输出仍然显示在终端;

顺序在这里是关键,因为重定向是从左到右执行的,所以不同的顺序会导致不同的结果。

| (pipe)

管道(pipe)用于将一个命令的标准输出作为下一个命令的标准输入。

ls -l | grep "txt"

这个命令将 ls -l 的输出通过管道传递给 grep "txt" 命令,从而过滤出包含 "txt" 的行。

【eg1】

将输出重定向到文件,可以使用 ">",后面跟上文件名。例如,"pwd > my_test" 执行 pwd 命令,并将 STDOUT 的内容重定向到文件 "my_test"。

如前所述,STDOUT 和 STDERR 分别对应数字 1 和 2。因此,使用 "2> my_test" 表示将 STDERR 的内容重定向到文件。

用 test.sh 脚本演示:

在上例中,STDOUT 被重定向到文件 "test_out",因此执行后,"Hello stderr" 仍会输出到 /dev/tty,而 "Hello stdout" 则会写入文件。

如果使用 "2>",结果就会相反:

文件输出本身可以一起使用,例如:

除了单独输出到文件外,还可以引用其他文件描述符。例如,使用 "2>&1" 可将 STDERR 重定向到 STDOUT。由于 "2>1" 的意思是 "将 STDERR 重定向到文件 1",因此添加"&1" 是为了引用 STDOUT,而不是文件。

整个概念如下,但由于当前输出是 /dev/tty,因此在使用上可能没有明显的区别:

下面是实现 "2>&1",将 STDERR 重定向到 STDOUT 的 C 代码示例:

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>int main()
{fwrite("For stdout\n", 11, 1, stdout);fwrite("For stderr\n", 11, 1, stderr);dup2(STDOUT_FILENO, STDERR_FILENO);fwrite("To Stdout \n", 11, 1, stdout);fwrite("To Stderr \n", 11, 1, stderr);return 0;
}

执行 “dup2(STDOUT_FILENO, STDERR_FILENO);” 之后,所有输出到 stderr 的内容都将重定向到与 stdout 相同的输出。

【eg2】

在了解 STDOUT 和 STDERR 之后,一个常见的要求是将 STDOUT 和 STDERR 写入同一个文件,其逻辑如下:

    合并 stdout 和 stderr 的输出;将合并结果输出到文件中;

因此,常见的解决方案是 "> file 2>&1", 错误用法是 "2>&1 > file" 两者虽看起来非常相似,但内在逻辑却不同;

首先,对于 "> file 2>&1",逻辑可以分为两个部分:

    > file => 将 STDOUT 的输出写入文件;2>&1 => 将 STDERR 的输出重定向到 STDOUT 的输入;

具体过程如下:

因此,STDOUT 和 STDERR 都可以写入文件。

对于 "2>&1 > file",如果把逻辑分解一下:

    2>&1 => 将 STDERR 的输出重定向到 STDOUT 的输出;> file=> 将 STDOUT 的输出写入文件;

整个过程如下,最后只有 STDOUT 的内容被写入文件:

另一个更简单方式是 "&> file",可以达到将 STDOUT 和 STDERR 写入文件达到相同效果:

【eg3】

在使用命令时,通常会将它们与管道 "|" 的概念结合起来。"|" 的基本思想是将当前命令的 "STDOUT" 重定向到下一条命令的 "STDIN",如下面的流程所示:

在下面的示例中,只有 STDOUT 被重定向到 grep 命令,而 STDERR 仍被输出到 /dev/tty:

如果还需要通过管道发送 STDERR 的内容,其概念与向文件写入内容类似,需要:

将 STDERR 重定向到 STDOUT;将下一条命令的 STDIN 连接到当前命令的 STDOUT;

五、 最后

本文简要介绍了 Bash 中常见的重定向技术,理解其原理就不需要再死记硬背如何将 STDERR 和 STDOUT 重定向到同一个文件,可以更严谨地思考如何实现各种要求。

原创 滑翔的纸飞机

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

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

相关文章

c#实现定时从外部服务器获取文件并查重(MD5)

需求:需要定时去请求外部服务器的文件,看看每天是否有新的文件上传,如果有就下载到本地服务器,并记录数据。原来的文件重命名。 方案:这里通过文件的MD5和其他条件来判断文件是否存在。因为文件量过大,所以批量下载的时候有时候会出现部分文件没能下载成功,但是数据入库…

Qt开发笔记:Qt3D三维开发笔记(一):Qt3D三维开发基础概念介绍

前言Qt3D是qt的三维,Q3D是Qt的三维图表,Qt3D是qt的自带的三维开发框架,Qt的3D开发分为opengl、Qt3D然后是第三方三维框架(OSG、vtk等等)多个技术流。  本篇描述Qt3D的基础概念,有一个基本知识。 个人经验,仅供参考(持续更新)通过深入研究和实践,从中长期看采取第三方…

VuePress日常使用

本篇来讲解下更多关于 VuePress 的基本用法本篇来讲解下更多关于 VuePress 的基本用法 ‍ 配置首页 现在的页面太简单了,我们可以对项目首页进行配置,修改 docs/README.md (这些配置是什么后面会说): --- home: true heroImage: https://s3.bmp.ovh/imgs/2022/12/02/bc742…

win10系统新建文件夹需刷新才能显示?原因及解决方法

在Win10操作系统中,一些用户可能会遇到这样一个问题:新建的文件夹在资源管理器中不会立即显示,需要刷新后才能看到。这给用户的日常操作带来了一定的困扰。接下来,系统世界官网将为您解析这一问题的原因以及相应的解决方法。一、原因分析1. 资源管理器缓存问题:在Win10系统…

【YOLOv8改进-损失函数】SlideLoss损失函数,解决样本不平衡问题

YOLO-FaceV2是基于YOLOv5的实时人脸检测模型,采用RFE模块增强小人脸检测,NWD损失处理定位偏差,SEAM注意力模块应对遮挡,Slide Loss解决样本不平衡,提升对难样本的关注。在WiderFace数据集上超越YOLO系列。论文和代码已公开。Slide Loss通过IoU加权,优化边界样本,提高模型…

使用Device Mapper创建线性阵列

​ 在之前的文章:《QEMU/KVM启动物理分区的Windows并调优》中笔者使用mdadm创建线性阵列,使VM启动物理硬盘分区上的Windows系统。这个做法思路清晰且具有实操性,但根据这个issue,Linux内核上游已将CONFIG_MD_LINEAR编译参数弃置了,这意味着在6.8及以后的内核中将无法使用m…

【YOLOv8改进-卷积Conv】DualConv( Dual Convolutional):用于轻量级深度神经网络的双卷积核

**摘要:**我们提出DualConv,一种融合$3\times3$和$1\times1$卷积的轻量级DNN技术,适用于资源有限的系统。它通过组卷积结合两种卷积核,减少计算和参数量,同时增强准确性。在MobileNetV2上,参数减少54%,CIFAR-100精度仅降0.68%。在YOLOv3中,DualConv提升检测速度并增4.4…

达梦数据库图形化安装

图形化安装(官网https://eco.dameng.com/document/dm/zh-cn/start/dm-instance-linux.html)启用图形化安装界面前需要通过如下命令将图形界面权限放开: Copy[root@localhost mnt]# xhost + access control disabled, clients can connect from any host [root@localhost mnt…

【YOLOv8改进-卷积Conv】 OREPA(Online Convolutional Re-parameterization):在线卷积重参数化

**OREPA**是在线卷积重参数化的缩写,它提出了一种两阶段流程来减少深度模型训练的开销。该方法通过线性缩放层优化复杂训练块,并在训练完成后将其压缩为单个卷积层,降低内存使用和提高训练速度。与现有技术相比,OREPA能减少约70%的训练内存开销,提升2倍训练速度,并在Imag…

【YOLOv8改进】 RFB (Receptive Field Block):多分支卷积块

**RFB Net是针对目标检测的轻量级解决方案,它通过设计灵感来自人眼感受野的模块提升特征表示。RFB块包含多分支卷积,模拟不同尺度和偏心率,增强轻量模型如SSD的性能。在保持实时速度的同时,RFB Net在准确性上媲美深度检测器。代码可在GitHub找到。**介绍摘要 当前表现最好的…

BUUCTF---天干地址+甲子

题目直接参考天干地支表作结,转ASCII flag{Goodjob}

BUUCTF---古典密码知多少

题目知识 一共给出四种古典密码,分别是:猪圈密码、圣堂武士密码、标准银河字母、栅栏密码 猪圈之前有介绍 圣:标准银河字母更多加密方式 解题 对照解密 FGCPFLIRTUASYON 再使用栅栏 FLAGISCRYPTOFUN flag{CRYPTOFUN}