Linux用文件表述符(file descriptor)来标识每个文件对象。
文件描述符是一个非负整数,可以唯一标识会话中打开的文件。
每个进程一次最多可以有9个文件描述符。
处于特殊目的,bash shell保留了前三个文件描述符(0,1,2):
文件描述符 | 缩写 | 描述 |
0 | STDIN | 标准输入 |
1 | STDOUT | 标准输出 |
2 | STDERR | 标准错误 |
这三个特殊文件表述符会处理脚本的输入和输出。
shell用它们将shell默认的输入和输出导向到相应的位置。
代表shell的标准输入。
对终端界面来说,标准输入是键盘。shell从STDIN文件表述符对应的键盘获得输入,在用户输入时处理每个字符。
在使用输入重定向符号(<)时,Linux会用重定向指定的文件来替换标准输入文件描述符。
当在命令行上只输入cat命令时,它会从STDIN接受输入。输入一行,cat命令就会显示出一行。
当然也可以通过STDIN重定向符号强制cat命令接受来自另一个非STDIN文件的输入。
如:cat < testfile
现在cat命令会用testfile文件中的行作为输入。
STDOUT代表shell的标准输出。
在终端界面上,标准输出就是终端显示器。
注意:shell对于错误消息的处理是跟普通输出分开的。
shell通过特殊的STDERR文件描述符来处理错误消息。
shell或shell中运行的程序和脚本出错时,生成的错误消息都会发送到这个位置。
STDERR和STDOUT指向同样的地方,尽管分配给它们的文件描述符值不同。即,默认情况下错误信息也会输出到显示器中。
注意:STDERR并不会随着STDOUT的重定向而发生改变。
将STDERR文件描述符值(2)放在重定向符号前(该值必须紧紧地放在重定向符号前,否则不工作)。
如:ls -al badfile 2> testfile
如果想重定向错误和正常输出,必须使用两个重定向符号。
需要在符号前面放上待重定向数据所对应的文件表述符,然后指向用于保存数据的输出文件。
如:
ls -al test test2 test3 badtest 2> test6 1> test7
shell利用 1> 符号将ls命令的正常输出重定向到了test7文件,而所有本该输出到STDERR的错误消息通过 2> 符号被重定向到test6.
也可以将STDERR和STDOUT的输出重定向到同一个输出文件。为此bash shell提供了特殊的重定向符号:&>
如:
ls -al test test2 test3 badtest &> test7
当使用 &> 符时,命令生成的所有输出都会发送到同一位置,包括数据和错误。
将单独的某一行输出重定向到STDERR,在重定向到文件表述符是,必须在文件表述符数字之前加上一个&
如:
echo "This is an error message." >&2
可以用exec命令告诉shell在脚本执行期间重定向某个特定文件描述符。
如: exec 1> testout
exec命令会启动一个新shell并将STDOUT文件描述符重定向到文件。脚本中发给STDOUT的所有输出会被重定向到文件。
exec命令可以将STDIN重定向到Linux系统上的文件中。
如: exec 0< testfile
这个命令会告诉shell它应该从文件testfile中获得输入,而不是STDIN。这个重定向只要在脚本需要输入时就会起作用。
将STDIN重定向到文件后,当read命令试图从STDIN读入数据时,它会到文件中去读取数据,而不是键盘。
shell会在脚本退出时自动关闭输入或输出文件描述符。当需要在脚本结束前关闭文件描述符时,需要用到:&-
如: exec 3>&-
该语句会关闭文件表述符3,不再脚本中使用它。
Linux使用/tmp目录来存放不需要永久保留的文件。大多数Linux发行版配置了系统在启动时自动删除/tmp目录的所有文件。
命令:mktemp
该命令会在/tmp目录中创建一个唯一的临时文件。shell会将这个文件的读写权限分配给文件的属主,并将创建者设成文件的属主。一旦创建了文件,在脚本中创建者就有了完整的读写权限,但其他人没法访问该文件。当然,root用户可以访问一切。
默认情况下,mktemp命令会在本地目录中创建一个文件。要用mktemp命令在本地目录中创建一个临时文件,只要指定一个文件名模板就行了。
模板可以包含任意文本文件名,在文件名末尾加上6个X就行了。
如:mktemp testing.XXXXXX
mktemp命令会用6个字符码替换这6个X,从而保证文件名在目录中使唯一的。
在脚本中使用mktemp命令时,需要将文件名保存到变量中,以便在脚本中引用。
如: tempfile=$(mktemp test1.XXXXXX)
用‘-t’选项,会强制mktemp命令在系统的临时目录中创建临时文件。这时mktemp命令会返回用来创建临时文件的全路径,而不是只有文件名。
用‘-d’选项,mktemp命令则会创建一个临时目录而不是临时文件。
如:tempdir=$(mktemp -d dir.XXXXXX)
将输出同时发送到显示器和日志文件。
命令:tee
tee命令就像管道的一个T型接头,它将从STDIN过来的数据同时发往两处,一处是STDOUT,另一处是tee命令行所指定的文件名。
格式:tee filename
注意:tee命令默认情况下,会在每次使用时覆盖输出文件的内容,所以要想追加内容到文件中,
需要使用‘-a’选项。
如:date | tee -a testfile
这一日期即显示在了屏幕上,也被追加到testfile文件中。