Bash 中的重定向 Linux 超级用户必须对 Bash 中的管道和重定向有很好的了解。这是系统中不可或缺的一部分,在 Linux 系统管理领域经常派上用场。 当你运行类似 ls , cat , etc, you get some output on the terminal. If you write a wrong command, pass a wrong flag or a wrong command-line argument, you get error output on the terminal. In both the cases, you are given some text.
Linux 超级用户必须对 Bash 中的管道和重定向有很好的了解。这是系统中不可或缺的一部分,在 Linux 系统管理领域经常派上用场。
当你运行类似 ls, cat, etc, you get some output on the terminal. If you write a wrong command, pass a wrong flag or a wrong command-line argument, you get error output on the terminal.
In both the cases, you are given some text. It may seem like "just text" to you, but the system treats this text differently. This identifier is known as a File Descriptor (fd).
In Linux, there are 3 File Descriptors, STDIN (0); STDOUT (1) and STDERR (2).
Both pipes and redirections redirect streams (文件描述符) of process being executed. The main difference is that redirections deal with 文件流, sending the output stream to a file or sending the content of a given file to the input stream of the process.
On the other hand a pipe connects two commands by sending the output stream of the first one to the input stream of the second one. without any redirections specified.
When you enter some input text for a command that asks for it, you are actually entering the text to the STDIN file descriptor. Run the cat command without any command-line arguments.
It may seem that the process has paused but in fact it's cat asking for STDIN. cat is a simple program and will print the text passed to STDIN. However, you can extend the use case by redirecting the input to the commands that take STDIN.
Example with cat 的命令时:
cat << EOF Hello World! How are you? EOF
这将简单地在终端屏幕上打印提供的文本:
Hello World! How are you?
同样的操作也可以用于通过 STDIN 接收输入的其他命令。例如,wc:
wc -l << EOF Hello World! How are you? EOF
-l flag with wc 用于统计行数。
这段 Bash 代码将在终端屏幕上打印行数:
2
终端屏幕上正常的非错误文本是通过 STDOUT 文件描述符打印出来的。可以将命令的 STDOUT 重定向到一个文件,这样命令的输出就会写入文件,而不是打印在终端屏幕上。
这只需借助 > and >> 操作符即可完成。
示例:
echo "Hello World!" > file.txt
上述命令不会在终端屏幕上打印 "Hello World",而是会创建一个名为 file.txt and will write the "Hello World" string to it.
This can be verified by running the cat command on the file.txt 的文件。
cat file.txt
然而,每次你将任何命令的 STDOUT 多次重定向到同一个文件时,它都会清除文件中已有的内容,然后写入新的内容。
示例:
echo "Hello World!" > file.txt echo "How are you?" > file.txt
运行 cat on file.txt 文件时:
cat file.txt
你只会看到 "How are you?" 字符串被打印出来。
How are you?
这是因为 "Hello World" 字符串已经被覆盖了。可以通过使用 >> 操作符来避免这种行为。
上述示例可以改写为:
echo "Hello World!" > file.txt echo "How are you?" >> file.txt
运行 cat on the file.txt 文件时,你将得到预期的结果。
Hello World! How are you?
另外,STDOUT 的重定向操作符也可以写成 1>。例如:
echo "Hello World!" 1> file.txt
终端屏幕上的错误文本是通过命令的 STDERR 打印出来的。例如:
ls --hello
会给出一条错误消息。这条错误消息就是该命令的 STDERR。
可以使用 2> 操作符来重定向 STDERR。
ls --hello 2> error.txt
此命令会将错误消息重定向到 error.txt file and write it to it. This can be verified by running the cat command on the error.txt file.
You can also use the 2>> operator for STDERR just like you used >> for STDOUT.
Error messages in Bash Scripts can be undesirable sometimes. You can choose to ignore them by redirecting the error message to the /dev/null file./dev/null——这是一个伪设备,它接收文本并立即丢弃。
上述示例可以改写如下,以完全忽略错误文本:
ls --hello 2> /dev/null
当然,你可以为同一命令或脚本同时重定向 STDOUT 和 STDERR。
./install_package.sh > output.txt 2> error.txt
它们也可以被重定向到同一个文件。
./install_package.sh > file.txt 2> file.txt
还有一种更简短的方法来实现这一点。
./install_package.sh > file.txt 2>&1
到目前为止,我们已经了解了如何将 STDOUT、STDIN 和 STDOUT 重定向到文件或从文件重定向。
要将一个程序(命令)的输出连接到另一个程序(命令)的输入,可以使用竖线 |。
示例:
ls | grep ".txt"
此命令会列出当前目录中的文件,并将输出传递给 grep 命令,后者会过滤输出,只显示包含 ".txt" 字符串的文件。
语法:
[time [-p]] [!] command1 [ | or |& command2 ] …
你还可以通过将多个命令串联起来形成任意的命令链,从而获得强大的效果。
这个示例会生成一个列表,列出给定目录中每个拥有文件的用户,以及他们拥有的文件和目录数量:
ls -l /projects/bash_scripts | tail -n +2 | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | sort | uniq -c
输出:
8 anne 34 harry 37 tina 18 ryan
符号 << 可以用来创建一个临时文件 [heredoc],并在命令行中从该文件进行重定向。
COMMAND << EOF ContentOfDocument ... ... EOF
请注意,EOF 表示 heredoc 的分隔符(文件结束)。实际上,我们可以使用任何字母数字词来代替它,以表示文件的开始和结束。例如,以下是一个有效的 heredoc:
cat << randomword1 This script will print these lines on the terminal. Note that cat can read from standard input. Using this heredoc, we can create a temporary file with these lines as it's content and pipe that into cat. randomword1
从效果上来看,heredoc 的内容似乎被管道传输到了命令中。如果需要将多行内容管道传输到某个程序,这可以使脚本非常简洁。
此外,我们还可以附加更多的管道,如图所示:
cat << randomword1 | wc This script will print these lines on the terminal. Note that cat can read from standard input. Using this heredoc, we can create a temporary file with these lines as it's content and pipe that into cat. randomword1
此外,预定义的变量也可以在 heredocs 中使用。
Herestrings 与 heredocs 非常相似,但使用 <<<。它们用于必须管道传输到某个程序的单行字符串。与 heredocs 相比,这种方法看起来更简洁,因为我们不需要指定分隔符。
wc <<<"this is an easy way of passing strings to the stdin of a program (here wc)"
与 heredocs 类似,herestrings 也可以包含变量。
| 操作符 | 描述 |
|---|---|
> |
将输出保存到文件 |
>> |
将输出追加到文件 |
< |
从文件读取输入 |
2> |
重定向错误消息 |
| |
将一个程序的输出作为另一个程序的输入 |
<< |
干净地将多行内容管道传输到程序 |
<<< |
干净地将一行内容管道传输到程序 |
免责声明:
本文件由基于人工智能的机器翻译服务翻译而成。尽管我们力求翻译准确,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言版本的文件为准。对于关键信息,建议使用专业的人工翻译。对于因使用本翻译而引起的任何误解或误读,我们概不负责。