概述
标准文件描述符和重定向
当在终端中执行命令时,大多数时候,命令的输出是显示在显示在屏幕上。有时候,需要将命令的输出输入到文件中或其它位置。这就涉及到了本文将要介绍的内容。
1. 标准输入输出
在 Linux 系统中,将每个对象都当作文件处理。这就包括输入和输出进程。Linux 用文件描述符(file descriptor)来标识每一个对象。文件描述符是一个非负整数,可以位移标识会话中打开的文件。每个进程一次最多可以有九个文件描述符。特别地,bash shell 保留了前三个文件描述符(0,1,2)。这三个文件描述符会处理脚本的输入和输出。shell 用它们将 shell 默认的输入和输出导向到指定的位置。
文件描述符 | 缩写 | 标准输入 |
---|---|---|
0 | STDIN | 标准输入 |
1 | STDOUT | 标准输出 |
2 | STDERR | 标准错误 |
1.1 标准输入 STDIN
STDIN 文件描述符代表 shell的标准输入。对终端界面来说,标准输入是键盘。shell从文件描述符对应的键盘获得输入。
使用重定向符 > 时,Linux 会用重定向指定的文件来替换标准输入文件描述符,读取文件的数据。
zzz@ubuntu:~/my_learning$ cat < files
This is Line1.
This is Line2.
This is Line3.
This is Line4.
zzz@ubuntu:~/my_learning$
1.2 标准输出 STDOUT
STDOUT文件描述符代表shell标准输出。在终端界面上,标准输出就是显示器。shell 的所有输出都会被定向到标准输出中,也就是显示器。可以使用重定向 > 来将输出导向到指定的文件。
zzz@ubuntu:~/my_learning$ cat files
This is Line1.
This is Line2.
This is Line3.
This is Line4.
zzz@ubuntu:~/my_learning$ cat files > files1
zzz@ubuntu:~/my_learning$ cat files1
This is Line1.
This is Line2.
This is Line3.
This is Line4.
zzz@ubuntu:~/my_learning$
使用 > 重定向输出,会覆盖的文件本有的内容。如果只是想将输出添加到指定文件的末尾,可以使用 >> 进行重定向。
1.3 标准错误 STDERR
shell 通过 STDERR 文件描述符来处理错误消息。STDERR 文件描述符代表shell的标准错误输出。shell 或 shell 中运行的程序和脚本出错时生成的错误消息都会发送到这里。默认情况下,STDERR和STDOUT指向同一个位置。但是,当STDOUT被重定向后,STDERR 指向的位置并不会随着改变。
如果需要重定向错误,可以和重定向标准输出类似,使用 2> 重定向错误输出。此时,运行命令,错误信息将被导入到指定的位置。这种方法只会重定向错误消息,而非普通数据。
如果需要同时重定向标准输出和标准错误。那么可以同时使用 1> 和 2> 重定向到两个文件或同一个文件。
ls -al test1 test2 1> file1 2> file2
bash shell 也提供了一个特殊的重定向符号 &> ,它将命令生成的所有输出都发送的到同一个位置,包括数据和错误。
ls -al test1 test2 &> file3
2. 在脚本中重定向输入输出
在脚本中,可以简单的通过 STDOUT 和 STDERR 文件描述符在多个位置生成输出。有两种方法在脚本中重定向输出:
- 临时重定向行输出
可以单独在某一行将输出重定向到 STDERR ,将输出信息重定向到 STDERR 指向的位置。使用重定向到文件描述符时,需要在文件描述符数字前加 & 。
echo "This is an error." >&2
在脚本 test3.sh 中,将 输出信息 “This is an error.” 重定向到 STDERR 指向的位置。此时,STDERR指向显示器,因此信息也被正常输出到显示器。如果在运行时,将脚本的 STDERR 重定向到文件,则 “This is an error.” 将被输出到文件file3中,而输出位置不变。
zzz@ubuntu:~/my_learning$ cat test3.sh
#!/bin/bash
echo "This is an error." >&2
echo "This is normal output."
zzz@ubuntu:~/my_learning$ ./test3.sh
This is an error.
This is normal output.
zzz@ubuntu:~/my_learning$
zzz@ubuntu:~/my_learning$
zzz@ubuntu:~/my_learning$ ./test3.sh 2> file3
This is normal output.
zzz@ubuntu:~/my_learning$
- 永久重定向脚本中所有的命令
可以使用 exec 命令告诉shell脚本执行期间重定向某个特定文件描述符。exec命令会启动一个新shell并将STDOUT文件描述符重定向到文件。脚本中发给STDOUT的所有输出会被重定向到文件中。
zzz@ubuntu:~/my_learning$ cat test3.sh
#!/bin/bash
exec 2> file4
echo "This is an error." >&2
echo "This is first output."
exec 1> file5
echo "This is second output."
zzz@ubuntu:~/my_learning$ ./test3.sh
This is first output.
zzz@ubuntu:~/my_learning$ cat file4
This is an error.
zzz@ubuntu:~/my_learning$ cat file5
This is second output.
zzz@ubuntu:~/my_learning$
- 脚本中重定向输入
可以使用exec命令将 STDIN 从键盘重定向到其它位置。
zzz@ubuntu:~/my_learning$ cat test4.sh
#!/bin/bash
exec 0< files
while read line
do
echo "$line"
done
zzz@ubuntu:~/my_learning$ ./test4.sh
This is Line1.
This is Line2.
This is Line3.
This is Line4.
zzz@ubuntu:~/my_learning$
3. 创建和使用文件描述符
以上注意介绍了3个默认的文件描述符。shell中最多可以有9个打开的文件描述符,其它3~8共6个文件描述符也可以被用作输入和输出的重定向。可以将这些文件描述符分配给文件,然后在脚本中使用它们。
3.1 创建使用输出文件描述符
可以在脚本中使用 exec 命令来分配文件描述符。下例中,(1) 将文件描述符3重定向到文件描述符1的当前位置,也就是 STDOUT 默认显示器;(2) 将 STDOUT 重定向到文件 file6,此时,shell 会将输出到 STDOUT 的输出直接重定向到文件 file6 中,但是此时文件描述符3 依旧指向原来位置,即显示器,所以(3) 输出到文件 file6 中;(4) 将文件描述符 STDOUT 重新重定向到文件描述符3指向的位置,即显示器,因此 (5) 输出到显示器。
zzz@ubuntu:~/my_learning$ cat test5.sh
#!/bin/bash
# (1)
exec 3>&1
# (2)
exec 1>file6
# (3)
echo "This is first output."
# (4)
exec 1>&3
# (5)
echo "This is second output."
zzz@ubuntu:~/my_learning$ ./test5.sh
This is second output.
zzz@ubuntu:~/my_learning$
zzz@ubuntu:~/my_learning$ cat file6
This is first output.
zzz@ubuntu:~/my_learning$
3.2 创建使用文件描述符
类似于输入文件描述符,在重定向到文件之前,可以先将 STDIN 保存到另一个文件描述符中,读取完文件之后在将 STDIN 恢复到原来的位置。
exec 4<&0
exec 0<file6
...
commands
...
exec 0<&4
3.3 创建使用读写文件描述符
以上都是将一个文件描述符只作为输入或者只作为输出,shell 也可以将一个文件描述符同时作为输入和输出描述符,此时 shell 会维护一个内部指针,指明在文件中的当前位置,任何读和写都会从文件指针上次的位置开始。
exec 3<>file7
3.4 关闭文件描述符
shell 会在脚本运行结束后,自动关闭脚本中创建的文件描述符。如果需要在脚本结束前手动关闭文件描述符,可以将文件描述符重定向到特殊符号 &-。如下:
exec 3>&-
3.5 null 文件
有时,需要将脚本的输出或错误丢弃,此时可以将 STDOUT or STDERR 重定向到一个特殊文件 /dev/null。null 文件中不会保存任何数据,shell 输出到 null 的全部数据会被丢弃。
zzz@ubuntu:~/my_learning$ ll > /dev/null
zzz@ubuntu:~/my_learning$ cat /dev/null
zzz@ubuntu:~/my_learning$
由于 null 文件的这个特性,可以使用它来达到快速清除现有文件中数据的目的,而不用删除文件再重新创建。
cat /dev/null > files8
最后
以上就是心灵美学姐为你收集整理的Linux 标准文件描述符和重定向标准文件描述符和重定向的全部内容,希望文章能够帮你解决Linux 标准文件描述符和重定向标准文件描述符和重定向所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复