【linux】Linux重定向
在Linux操作系统中,命令行界面是一个强大的工具,它允许用户与系统进行高效的交互。重定向是命令行中一个非常重要的概念,它可以改变命令输入和输出的默认路径。通过重定向,用户可以将数据从一个程序传递到另一个程序,或者保存到文件中,这使得数据处理变得更加灵活和高效。
重定向是一种改变命令输入输出流的机制。默认情况下,大多数命令从标准输入(stdin,通常是键盘)读取数据,将结果输出到标准输出(stdout,通常是屏幕),并将错误消息输出到标准错误(stderr,也通常是屏幕)。重定向允许我们改变这些数据流的方向,从而可以将数据从一个文件或设备转移到另一个文件或设备。
重定向操作符允许我们改变这些通道的方向。例如,我们可以使用>操作符将命令的输出保存到一个文件中,而不是打印到屏幕上。
标准输入输出流
在深入了解重定向之前,我们需要先理解标准输入、输出和错误这三个概念。每当我们执行一个命令时,它通常会从标准输入(stdin)读取数据,将结果输出到标准输出(stdout),并将错误信息输出到标准错误(stderr)。这三个通道默认情况下都是连接到我们的终端,即我们的屏幕和键盘。
每一个进程的fd目录下都会有0、1、2这三个文件描述符:
- 0:标准输入流
- 1:标准输出流
- 2:标准错误流
$$变量用于获取当前进场的PID。
标准输入输出流的重定向
标准输出重定向(stdout)
>符号用于将命令的输出重定向到一个文件,如果文件已存在,则会被覆盖。
$ echo "Hello, World!" > output.txt $ echo "Hello, World!" 1> output.txt $ cat output.txt Hello, World!命令中的1是一个文件描述符,表示标准输出流,<左边默认文件描述符的值就是1,所以可以省略。
>>符号用于将命令的输出追加到一个文件的末尾,而不是覆盖它。
$ echo "Hello, World!" 1>> output.txt $ echo "Hello, World!" >> output.txt $ cat output.txt Hello, World! Hello, World! Hello, World!在使用重定向时,可能会遇到各种问题。例如,不小心使用>而不是>>可能会导致原有文件内容的丢失。为了避免这种情况,我们应该在执行命令前仔细检查所使用的重定向操作符。此外,学习如何使用Shell脚本中的条件语句来检查文件是否存在,也可以帮助我们避免数据覆盖的问题。
标准错误重定向(stderr)
2>符号用于将错误信息重定向到一个文件,如果文件已存在,则会被覆盖。
$ ls not_existing_file 2> error.txt $ cat error.txt ls: cannot access 'not_existing_file': No such file or directory命令中的2是一个文件描述符,表示标准错误流。
2>>符号用于将错误信息追加到一个文件的末尾。
$ 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)
<符号用于将文件的内容作为命令的输入。
$ read a < output.txt $ echo $a Hello, World!read指令读到换行符\n就会停止,所以read a < output.txt会将output.txt文件的第一行读取到并赋值给变量a。
重定向的组合使用
stdin和stdout的组合使用
将cat的标准输入重定向为test.txt, 将其标准输出重定向为cat.out。
$ 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屏幕上:
$ ls ./ no_exist_file 1> stdout.out ls: cannot access 'no_exist_file': No such file or directorystdout重定向到文件stdout.out,stderr重定向到文件stderr.out:
$ 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 directorystdint和stdout重定向到相同文件
可以同时重定向stdout和stderr到同一个文件。
&>用于同时将标准输出和标准错误重定向到同一个文件。
$ 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或者使用更具体的描述符组合:
$ ls ./ no_exist_file 1> output.txt 2>&1 $ ls ./ no_exist_file 2> output.txt 1>&2注意1>s.out和2>&1的顺序不能反过来,另外1前面要加&,否则会以为1是一个普通的文件,而不是文件描述符。
1>s.out和2>&1的顺序伪代码解释:
// 伪代码 // 初始 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,这会丢弃所有重定向到它的数据。
$ command > /dev/null 2>&1创建空文件
使用重定向也可以快速地创建空文件:
$ touch newfile.txt # 常规方法 $ > newfile.txt # 通过重定向创建空文件Here文档(Here Documents)
Here文档是一种特殊的重定向方式,它允许你将多行输入直接在命令行中指定,而不是来自文件或键盘输入。
$ cat << EOF > output.txt > first > second > EOF $ cat output.txt first secondHere字符串(Here Strings)
Here字符串是Here文档的简化版,它允许你将单行输入重定向到命令。
$ cat <<< "This is a single line"重定向是Linux中一个非常强大的特性,它让用户能够灵活地控制命令的输入和输出。通过熟练使用重定向,可以在脚本编写和日常任务中实现更加复杂和高效的数据处理。