重定向和管道是两个有用的功能 bash 系统管理员和开发人员经常使用的脚本。 在本指南中,我们将讨论什么是 Bash 重定向 以及如何在 Bash 中使用重定向 example 命令。
在了解重定向的工作原理之前,了解什么是文件描述符很重要。
什么是文件描述符?
当你在 Linux 中打开一个文件时,每个文件都会被分配一个 Integer,这个信息存储在内核中。 这样内核就知道打开了哪些文件以及打开了哪些文件。 分配的整数编号就是我们所说的文件描述符(简称 FD)。
默认情况下,每个程序都将从三个文件描述符开始。
- FD 0 -> 标准输入(stdin)-> 键盘
- FD 1 -> 标准输出(Stdout)-> 显示(终端)
- FD 2 -> 标准错误(Stderr)-> 显示(终端)
您可以在中查看文件描述符 /dev
目录:
$ ls -l /dev/std* lrwxrwxrwx 1 root root 15 Aug 27 21:32 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Aug 27 21:32 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Aug 27 21:32 /dev/stdout -> /proc/self/fd/1
Stdin (FD0) 从键盘获取输入。 stdout (FD1) 和 stderr (FD2) 被发送到终端。 使用管道和重定向时,您可以更改输入传递、输出和错误发送到的方式。
将输出重定向到文件
如前所述,任何程序的输出(stdout)和错误(stderr)都会发送到终端。 您可以使用 重定向运算符“>” 将标准输出和标准错误写入文件。
看看下面 example. 我正在运行 uname -mrs
命令并将输出重定向到一个名为 uname.log
.
$ uname -mrs > uname.log
$ cat uname.log
Linux 5.10.0-8-amd64 x86_64
小心: 使用时 ">"
运算符,如果文件不可用,则会创建它。 如果文件已经存在,它将被新内容覆盖。
您还可以将文件描述符编号用于 标准输出(1) 在重定向运算符之前将输出重定向到文件。
$ uname -mrs 1> uname.log
就像我已经提到的,单个重定向运算符 (>
) 只会覆盖文件的内容,如果文件已经存在。 但是,如果您想追加内容而不是覆盖到同一个文件,请使用双重定向运算符(即 >>
)。 您也可以在这里使用标准输出文件描述符(1)。
$ whoami >> uname.log
$ echo $SHELL 1>> uname.log
$ cat uname.log Linux 5.10.0-8-amd64 x86_64 ostechnix /bin/bash
如何处理标准错误
每个程序都会产生输出和错误,并且都被发送到终端。 在许多情况下,您可能希望忽略错误或隔离错误并将其重定向到单独的文件以进行故障排除。
我们来个简单的 example 的运行 ls
命令来看看它是如何工作的。 我试图列出两个文件,其中只有一个存在。 正如我已经说过的,我在终端中得到了我的错误和输出。
$ ls -l uname.log u1.log ls: cannot access 'u1.log': No such file or directory -rw-r--r-- 1 ostechnix ostechnix 48 Aug 27 07:37 uname.log
我也一样 ls
再次命令,但这次将输出重定向到文件。 从输出中可以看出 >
运算符将 stdout(1) 重定向到文件,但 stderr(2) 被发送到终端。
$ ls -l uname.log u1.log > ls.op ls: cannot access 'u1.log': No such file or directory
要将 stderr 重定向到文件,请使用 "2>"
操作员。 必须在重定向运算符 > 之前使用 stderr(2) 的文件描述符,这会将错误单独发送到文件。
$ ls -l uname.log u1.log > ls.op 2> ls.err
$ cat ls.err ls: cannot access 'u1.log': No such file or directory
现在,stdout 和 stderr 被写入单独的文件。 您也可以将 stdout 和 stderr 发送到单个文件。
$ ls -l uname.log u1.log 1> ls.op 2> ls.op
从 bash 4.4你也可以使用 &>
签名以将 stdout 和 stderr 都重定向到文件。
$ ls -l uname.log u1.log &> ls.op
什么是 /dev/null?
Null 是一个字符特殊文件,它接受输入并丢弃输入并且不产生输出。 简而言之,null 会丢弃您重定向到它的任何内容。
$ ls -l /dev/null crw-rw-rw- 1 root root 1, 3 Aug 27 06:01 /dev/null
为什么 null 在重定向中很重要? 你可能想知道。 在某些情况下,您可能不希望打印或存储 stdout 或 stderr。 在这种情况下,您可以将 stdout 或 stderr 重定向到 /dev/null ,这将丢弃输入流。
$ date > /dev/null $ date 1> /dev/null # Stdout to Null $ dateee 2> /dev/null # WRONG COMMAND, Stderr to Null $ date &> /dev/null # Stdout/Stderr to Null
Bash 中的输入重定向
与将输出和错误重定向到文件的方式类似,您也可以使用输入重定向运算符 (<
)。
让我们从一个简单的字数统计程序开始。 在这里,我正在重定向的内容 ostechnix.txt
文件到字数以查找行数。
$ wc -l < ostechnix.txt 10
您还可以在重定向输入时传递标准输入文件描述符 (0)。
$ wc -l 0< ostechnix.txt 10
您可以组合输入和输出重定向运算符,如下所示。
$ wc -l < ostechnix.txt &> /tmp/wc.op
$ cat /tmp/wc.op 10

输入重定向将与 while 循环一起使用,以逐行读取文件的内容。
看看下面 example. 我正在通过 /etc/passwd
文件作为输入 while
命令。 这里 read
命令将逐行读取并将其存储在变量中 VAL
并进一步在循环条件中写入以检查用户是否可用。
while read VAL; do NAME=$(echo $VAL | awk -F ":" '/1/ {print $1}' ) if [[ $NAME = "karthick" ]] then echo "User spotted" fi done < /etc/passwd
查找系统用户的脚本
将上述代码中的“karthick”替换为您的系统用户名。 Save 文件和 close 它。
这不是实现查找用户任务的最佳方式,但出于演示目的,这样做可以。
现在,使脚本可执行并运行它:
$ chmod +x ostechnix.sh
$ ./ostechnix.sh
User spotted
Bash 支持另一种形式的输入重定向,称为 赫雷多克. 有关更多详细信息,请参阅以下指南:
- Bash Heredoc 初学者教程
概括
在本指南中,我们学习了一些重要的脚本概念,例如什么是 Bash 重定向、什么是文件描述符、如何将输出重定向到文件、如何处理 stderr、什么是 /dev/null 以及它在 Bash 中的使用方式重定向,最后我们用 Bash 中的输入重定向结束了指南。
如果你想学习 Bash 脚本,你应该学习并熟悉这里解释的概念。 为了让自己舒服,我建议您在您的系统中尝试我们在本文中显示的所有命令。
如果您有任何反馈或任何提示可以帮助 Linux 社区和我们的读者学习 bash 脚本,请随时在下面的评论部分告诉我们。
建议阅读:
- Bash 脚本——用例子解释的变量
- Bash 脚本——用例子解释的函数
- Bash 脚本——用例子解释 For 循环
- Bash 脚本 – While 和 until 循环用示例解释
- 用 Linux 中的示例解释 Bash Echo 命令
- 有用的 Bash 键盘快捷键列表
- 定义带和不带导出的 Bash 变量之间的区别