Linux 中的输入/输出重定向

        Redirection in Linux 是一种在 Linux 中执行命令时,可以改变标准输入输出设备的功能。Linux 命令的基本流程是接收输入并产生输出,但是可以使用重定向技术来改变标准输入(stdin)或标准输出(stdout)的来源或目的地。例如,可以将命令的输出保存到文件中,而不是显示在屏幕上,或者可以将文件中的内容作为命令的输入,而不是从键盘输入。

Linux 中有三种数据流参与了命令的执行:

  • 标准输入(stdin)是输入数据的来源。默认情况下,stdin 是从键盘输入的任何文本。它的流 ID 是 0。
  • 标准输出(stdout)是命令的结果。默认情况下,它显示在屏幕上。它的流 ID 是 1。
  • 标准错误(stderr)是命令产生的错误信息(如果有的话)。默认情况下,stderr 也显示在屏幕上。它的流 ID 是 2。

        这些流包含了以纯文本形式存储在缓冲区内存中的数据。可以使用一些特殊的符号或命令来重定向这些流,例如:

  • 输出重定向:使用 “>” 或 “>>” 符号来将 stdout 重定向到一个文件中。如果使用 “>” 符号,那么原有文件的内容会被覆盖;如果使用 “>>” 符号,那么新的输出会追加到原有文件的末尾。
  • 输入重定向:使用 “<” 或 “<<” 符号来将 stdin 重定向到一个文件中。如果使用 “<” 符号,那么命令会从指定文件中读取输入;如果使用 “<<” 符号,那么命令会从终端中读取以指定分隔符结束的多行输入。
  • 错误重定向:使用 “2>” 或 “2>>” 符号来将 stderr 重定向到一个文件中。如果使用 “2>” 符号,那么原有文件的内容会被覆盖;如果使用 “2>>” 符号,那么新的错误信息会追加到原有文件的末尾。

什么是文件描述符?

        文件描述符是与系统上打开的文件关联的非负整数。需要注意的是,文件描述符绑定到一个进程,并且每个进程都是唯一的。打开新文件时,内核会返回与其关联的文件描述符。有三个与您的终端关联的标准文件描述符。

当bash启动时,默认情况下它会打开三个文件描述符(fd)

  • stdin (fd 0)
  • stdout (fd 1)
  • stderr (fd 2)

        所有这三个文件描述符都指向你的终端(例如 /dev/tty0),因此从你的终端读取输入,输出和错误被重定向到你的终端。 

stdin   (fd0)  -----> /dev/tty0
stdout  (fd1)  -----> /dev/tty0
stderr  (fd2)  -----> /dev/tty0

        这就是默认重定向的样子。但这些可以根据我们的需要进行更改。了解重定向如何工作的最佳方法是将它们可视化。

什么是重定向呢?

重定向是将默认位置操作到标准文件描述符(stdin、stdout、stderr)指向的位置的过程。

将命令的输出重定向到文件:

Syntax:
<command> n> file_name
Examples:
$ ls -la > list_file.txt
$ ls -la 1> list_file.txt

 示例中的上述两个命令完全相同。如果未将文件描述符编号与重定向符号 (>) 一起指定,则默认为文件描述符 1(stdout 文件描述符)。请参阅下面的重定向可视化

fd0  -----> /dev/tty0
fd1  -----> list_file.txt
fd2  -----> /dev/tty0

 

将标准输出和标准输出重定向到文件:

这是常用的方案之一,其中命令的流、stdout 和 stderr 的输出都重定向到文件

 

$ command &> file
$ command >file 2&>1

以下是执行上述行后命令的文件描述符表的变化方式。

Original                         After the redirection
0 ------> /dev/tty0              0 ---------> /dev/tty
1 ------> /dev/tty0              1 ------|--> file
2 ------> /dev/tty0              2 ------| 

重定向的顺序在这里很重要。如果重定向顺序被交换,则只有标准输出最终会重定向到文件。尝试按照上面的示例进行可视化

通过命令的 stdin 输入文件的内容:

将文件的内容重定向到命令的 stdin。此方案通常用于读取命令,其中文件可以作为读取的输入传递,而不是从终端读取

read -n 5  < input_file.txt
0 -----> input_file.txt
1 -----> /dev/tty0
2 -----> /dev/tty0

将执行的所有命令的 stderr 重定向到终端会话中的文件:

如果您想将 shell 会话中执行的所有命令的输出重定向到特定文件,下面的这个命令非常有用!

$ exec 2>file
$ test_command1
$ test_command2

 

如何打开新的文件描述符进行读写?

        可以创建自定义文件描述符并将其指向文件,此文件描述符可用于读取和写入文件,具体取   决于您的数字。此用例介绍了内置 bash 命令 — exec 的用法。此内置命令 ,如果在重定向之前 指定,将使它们有效,直到您明确更改重定向或退出 shell 或脚本exec

使用自定义文件描述符打开文件进行读取:

# point a file descriptor to file
$ exec 7<file_name
# Reads a line from the file pointed by filedescriptor 7
$ read -u 7 line
# close fd after reading
$ exec 7>&-

 

使用自定义文件描述符写入文件:

这类似于将某些内容写入 stdout,只是您将有一个额外的步骤将文件描述符指向要写入的文件。

$ exec 3<file_write
$ echo "Test message" > &3
$ echo 3>&-

 要打开文件以进行读取和写入,可以使用以下exec命令

#Use file descriptor for both reading and writing - Filename: Test.txt
$ exec 3 <>Test.txt

更多 bash 单行代码的示例:

丢弃命令输出:

重定向到特殊文件 /dev/null 将避免将命令的输出打印到 stdout。/dev/null 是 Linux 中用于写入输出的众多虚拟文件之一。写入 /dev/null 的任何内容都会被遗忘,并且永远不会打印出来

$ test_command < /dev/null

从终端输入命令:

可以通过从终端获取输入来创建文件并在单个命令中添加内容。下面是一个示例。以下<<EOF的语法称为heredoc。

$ cat > 'temp.txt' <<EOF
Always in love with bash and 
all the things we could do with it.
EOF

将标准输出打印到终端和文件:

从技术上讲,Tee 不是 bash 的一部分,但经常使用。它将输入流复制到标准输出以及零个或多个文件。相信我,这非常方便,尤其是在调试时。

command -----> tee -----> stdout
                |--------> file

Pipe在哪里使用?

Pipe 是 Linux 中的一种重定向功能,可以将一个命令/程序/进程的输出发送到另一个命令/程序/进程作为输入,从而实现命令之间的协作。Pipe 的符号是 “|”,可以用来连接多个命令,形成一个命令管道。例如:

ls | grep "txt" | wc -l

这个命令管道的作用是先列出当前目录下的所有文件,然后筛选出包含 “txt” 的文件,最后统计这些文件的数量。每个命令的输出都成为下一个命令的输入,直到最后一个命令的输出显示在终端上。

pipe最常见的用例是将一个命令的输出作为另一个命令的输入发送。

Syntax:
command1 | command2
Examples:
$ ls . > file.txt
$ wc -l file.txt
The above two commands are equivalent to this one-liner
$ ls . | wc -l

 此单行可用于将命令的 stdout 和 stderr 发送到另一个命令的 stdin。

command1 2>&1 | command2

 重定向单行文本,作为另一个命令的输入

echo “Test text” | test_command

 “Test text”现在输入test_command.

本文介绍了 Linux 中的重定向和管道功能,以及如何使用它们来实现命令之间的协作和数据流的控制。通过一些简单的例子,我们展示了如何使用 test 命令来测试命令或表达式的有效性,以及如何检查文件的类型和权限。我还介绍了一些常用的重定向和管道操作符,以及它们的含义和用法。希望本文能够帮助你更好地理解和使用 Linux 中的重定向和管道功能,提高你的命令行技能和效率。

感谢你阅读本文,如果你觉得本文对你有帮助,请给我一个赞或者留下你的评论。如果你有任何问题或建议,也欢迎你与我联系。我会尽力回复你的问题,并不断改进我的博客内容。再次感谢你的支持和关注,祝你学习愉快!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简化解

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值