重定向和管道是两个有用的功能 bash 系统管理员和开发人员经常使用的脚本。 在本指南中,我们将讨论什么是 Bash 重定向 以及如何使用示例命令在 Bash 中使用重定向。
在了解重定向的工作原理之前,了解什么是文件描述符很重要。
内容
什么是文件描述符?
当你在 Linux 中打开一个文件时,每个文件都会被分配一个整数,这个信息存储在内核中。 这样内核就知道打开了哪些文件以及哪个进程打开了这些文件。 分配的整数号就是我们所说的文件描述符(简称 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) 都会发送到终端。 您可以使用 重定向运算符“>” 将标准输出和标准错误写入文件。
看看下面的例子。 我正在运行 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
就像我已经提到的,单个重定向运算符 (>
) 只会覆盖文件的内容,如果文件已经存在。 但是,如果您想追加内容而不是覆盖同一文件,请使用双重重定向运算符(即 >>
)。 您也可以在此处使用 stdout 文件描述符 (1)。
$ whoami >> uname.log
$ echo $SHELL 1>> uname.log
$ cat uname.log Linux 5.10.0-8-amd64 x86_64 ostechnix /bin/bash
如何处理 Stderr
每个程序都会生成输出和错误,并且都被发送到终端。 在许多情况下,您可能希望忽略错误或隔离错误并将其重定向到单独的文件以进行故障排除。
让我们举一个简单的例子来运行 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
为什么空值在重定向中很重要? 你可能想知道。 在某些情况下,您可能不希望打印或存储 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
您还可以在重定向输入时传递 stdin 文件描述符 (0)。
$ wc -l 0< ostechnix.txt 10
您可以组合输入和输出重定向运算符,如下所示。
$ wc -l < ostechnix.txt &> /tmp/wc.op
$ cat /tmp/wc.op 10
输入重定向将与 while 循环一起使用以逐行读取文件的内容。
看看下面的例子。 我正在通过 /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 变量的区别
BASHBash 重定向Bash 脚本Bash shellLinuxLinux 管理Linux bascsLinux 命令Linux howtoPipingRedirectionScriptingShell scripting