【linux】Linux重定向

在Linux操作系统中,命令行界面是一个强大的工具,它允许用户与系统进行高效的交互。重定向是命令行中一个非常重要的概念,它可以改变命令输入和输出的默认路径。通过重定向,用户可以将数据从一个程序传递到另一个程序,或者保存到文件中,这使得数据处理变得更加灵活和高效。

重定向是一种改变命令输入输出流的机制。默认情况下,大多数命令从标准输入(stdin,通常是键盘)读取数据,将结果输出到标准输出(stdout,通常是屏幕),并将错误消息输出到标准错误(stderr,也通常是屏幕)。重定向允许我们改变这些数据流的方向,从而可以将数据从一个文件或设备转移到另一个文件或设备。

重定向操作符允许我们改变这些通道的方向。例如,我们可以使用>操作符将命令的输出保存到一个文件中,而不是打印到屏幕上。

标准输入输出流

在深入了解重定向之前,我们需要先理解标准输入、输出和错误这三个概念。每当我们执行一个命令时,它通常会从标准输入(stdin)读取数据,将结果输出到标准输出(stdout),并将错误信息输出到标准错误(stderr)。这三个通道默认情况下都是连接到我们的终端,即我们的屏幕和键盘。

每一个进程的fd目录下都会有0、1、2这三个文件描述符:

  • 0:标准输入流
  • 1:标准输出流
  • 2:标准错误流
shell 复制代码
$ ll /proc/$$/fd
total 0
dr-x------ 2 vagrant vagrant  0 Dec 25 01:46 ./
dr-xr-xr-x 9 vagrant vagrant  0 Dec 25 01:46 ../
lrwx------ 1 vagrant vagrant 64 Dec 25 01:46 0 -> /dev/pts/0
lrwx------ 1 vagrant vagrant 64 Dec 25 01:46 1 -> /dev/pts/0
lrwx------ 1 vagrant vagrant 64 Dec 25 01:46 2 -> /dev/pts/0

$$变量用于获取当前进场的PID。

标准输入输出流的重定向

标准输出重定向(stdout)

>符号用于将命令的输出重定向到一个文件,如果文件已存在,则会被覆盖。

shell 复制代码
$ echo "Hello, World!" > output.txt

$ echo "Hello, World!" 1> output.txt

$ cat output.txt
Hello, World!

命令中的1是一个文件描述符,表示标准输出流,<左边默认文件描述符的值就是1,所以可以省略。

>>符号用于将命令的输出追加到一个文件的末尾,而不是覆盖它。

shell 复制代码
$ echo "Hello, World!" 1>> output.txt

$ echo "Hello, World!" >> output.txt

$ cat output.txt
Hello, World!
Hello, World!
Hello, World!

在使用重定向时,可能会遇到各种问题。例如,不小心使用>而不是>>可能会导致原有文件内容的丢失。为了避免这种情况,我们应该在执行命令前仔细检查所使用的重定向操作符。此外,学习如何使用Shell脚本中的条件语句来检查文件是否存在,也可以帮助我们避免数据覆盖的问题。

标准错误重定向(stderr)

2>符号用于将错误信息重定向到一个文件,如果文件已存在,则会被覆盖。

shell 复制代码
$ ls not_existing_file 2> error.txt

$ cat error.txt
ls: cannot access 'not_existing_file': No such file or directory

命令中的2是一个文件描述符,表示标准错误流。

2>>符号用于将错误信息追加到一个文件的末尾。

shell 复制代码
$ ls not_existing_file 2>> error.txt

$ cat error.txt
ls: cannot access 'not_existing_file': No such file or directory
ls: cannot access 'not_existing_file': No such file or directory

标准输入重定向(stdin)

<符号用于将文件的内容作为命令的输入。

shell 复制代码
$ read a < output.txt

$ echo $a
Hello, World!

read指令读到换行符\n就会停止,所以read a < output.txt会将output.txt文件的第一行读取到并赋值给变量a。

重定向的组合使用

stdin和stdout的组合使用

将cat的标准输入重定向为test.txt, 将其标准输出重定向为cat.out

shell 复制代码
$ cat 0< output.txt 1> cat.out

$ cat cat.out
Hello, World!
Hello, World!
Hello, World!

这样完成了将output.txt复制为cat.out文件,相当于cp命令。

stdout和stderr重定向到不同文件

stdout重定向到文件stdout.out,stderr不重定向,默认还是会显示在shell屏幕上:

shell 复制代码
$ ls ./ no_exist_file 1> stdout.out
ls: cannot access 'no_exist_file': No such file or directory

stdout重定向到文件stdout.out,stderr重定向到文件stderr.out

shell 复制代码
$ ls ./ no_exist_file 1> stdout.out 2> stderr.out

$ cat stdout.out
./:
cat.out
error.txt
ooxx.txt
output.txt
stderr.out
stdout.out

$ cat stderr.out
ls: cannot access 'no_exist_file': No such file or directory

stdint和stdout重定向到相同文件

可以同时重定向stdout和stderr到同一个文件。

&>用于同时将标准输出和标准错误重定向到同一个文件。

shell 复制代码
$ ls ./ no_exist_file &> output.txt

$ cat output.txt
ls: cannot access 'no_exist_file': No such file or directory
./:
cat.out
error.txt
ooxx.txt
output.txt
stderr.out
stdout.out

或者使用更具体的描述符组合:

shell 复制代码
$ ls ./ no_exist_file 1> output.txt 2>&1

$ ls ./ no_exist_file 2> output.txt 1>&2

注意1>s.out2>&1的顺序不能反过来,另外1前面要加&,否则会以为1是一个普通的文件,而不是文件描述符。

1>s.out2>&1的顺序伪代码解释:

shell 复制代码
// 伪代码
// 初始
fd1 = stdout
fd2 = stderr

// 1> output.txt 2>&1
fd1 = output.txt
fd2 = fd1 // fd2指向output.txt

// 2>&1 1> output.txt
fd2 = fd1 // fd2指向stdout
fd1 = output.txt

特殊的重定向情况

丢弃输出

有时候,我们可能不想要命令的输出,这时可以将输出重定向到特殊的文件/dev/null,这会丢弃所有重定向到它的数据。

shell 复制代码
$ command > /dev/null 2>&1

创建空文件

使用重定向也可以快速地创建空文件:

shell 复制代码
$ touch newfile.txt  # 常规方法
$ > newfile.txt      # 通过重定向创建空文件

Here文档(Here Documents)

Here文档是一种特殊的重定向方式,它允许你将多行输入直接在命令行中指定,而不是来自文件或键盘输入。

shell 复制代码
$ cat << EOF > output.txt
> first
> second
> EOF

$ cat output.txt
first
second

Here字符串(Here Strings)

Here字符串是Here文档的简化版,它允许你将单行输入重定向到命令。

shell 复制代码
$ cat <<< "This is a single line"

重定向是Linux中一个非常强大的特性,它让用户能够灵活地控制命令的输入和输出。通过熟练使用重定向,可以在脚本编写和日常任务中实现更加复杂和高效的数据处理。

相关推荐
远游客07135 分钟前
centos stream 8下载安装遇到的坑
linux·服务器·centos
马甲是掉不了一点的<.<5 分钟前
本地电脑使用命令行上传文件至远程服务器
linux·scp·cmd·远程文件上传
jingyu飞鸟6 分钟前
centos-stream9系统安装docker
linux·docker·centos
超爱吃士力架35 分钟前
邀请逻辑
java·linux·后端
cominglately3 小时前
centos单机部署seata
linux·运维·centos
魏 无羡3 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
CircleMouse3 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
木子Linux4 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
mit6.8244 小时前
Ubuntu 系统下性能剖析工具: perf
linux·运维·ubuntu
鹏大师运维4 小时前
聊聊开源的虚拟化平台--PVE
linux·开源·虚拟化·虚拟机·pve·存储·nfs