您可以通过两种方式显示shell脚本的输出,在屏幕上显示输出或者将输出发送到文件。
在本教程中我们说明Shell脚本中必不可少的知识,即标准输入、标准输出和重定向。
在Linux 一切都是文件,包括输入和输出。每个进程都可以同时打开九个文件描述符。保留的文件描述符0、1、2提供shell进程使用。
0
表示标准输入。1
表示标准输出。2
标准错误。您可以使用这些文件描述符来控制程序或者脚本的输入和输出。
您需要完全理解这三个概念,因为它是Shell脚本或者程序的支柱。因此,我们将详细描述它们中的每一个。
STDIN
代表标准输入,也就是文件描述符1
,默认为键盘。您可以使用重定向符号<
将指定文件作为标准输入。
如果你将标准输入替换为文件,重定向符号<
会将的文件数据作为标准输入传递给指定的程序。
例如命令cat < archive.tar | gzip -c > archive.tar.gz
使用重定向符号<
将archive.tar
文件作为标准输入传递给cat命令。
cat命令接收标准输入后,又将archive.tar
文件内容写入标准输出,最后通过管道传递给gzip命令进行压缩。
cat < archive.tar | gzip -c > archive.tar.gz
STDOUT
代表标准输出,也就是文件描述符2
,默认为屏幕。您可以使用重定向符号>>
,>
将标准输出重定向到文件。
您可以使用重定向符号>>
将数据追加到指定文件。例如命令pwd >> log
会将pwd
命令的标准输出追加到文件log。
而重定向符号>
则会使用标准输出覆盖指定文件。例如命令> filename
将会清空文件filename
。
pwd >> log
> filename
ls file2 > file
命令尝试使用重定向>
符号将标准输出重定向到文件。如果你的计算机没有xfile文件。
ls
命令将会打印一个错误ls: cannot access 'file2': No such file or directory
,这通常称为标准错误STDERR
。
默认情况下,Shell将标准错误发送到屏幕。如果您需要将标准错误重定向到日志文件,可以使用重定向符号>
/>>
重定向错误。
ls file2 > file
ls: cannot access 'file2': No such file or directory
正如引言所提到文件描述符2
是标准错误,因此我们将文件描述符2
放在重定向符号之前来重定向错误。
假设当前目录不存在文件xfile,现在运行ls -l xfile 2> log
命令将会把错误重定向到文件log,2>
表示重定向标准错误。
如您所见错误消息并没有打印在屏幕,而是写入到文件,你可以运行cat命令查看文log
文件内容。
ls -l xfile 2> log
要重定向错误和标准输出,您必须在每个重定向符号之前添加正确的文件描述符。在同一命令可以使用多个重定向符号来实现标准错误和标准错误的重定向。
假设当前目录存在文件file1,但不存在文件file2。现在运行命令ls flie1 file2
将会同时产生标准错误和标准输出。
出于某种原因,你可能需要标准错误写入到文件error.log,而标准输出写入文件access.log。
此时你就可以使用文件描述1
和重定向符号>
写入到access.log
文件,组合之后的符号是1>
。
使用文件描述符2
和重定向符好>
送到写入到error.log文件,组合之后的符号是2>
。因此最终的命令是ls file1 file2 2> error.log 1> access.log
。
除此之外您还可以使用&>
符号将标准输出和标准错误重定向到同一个文件。例如命令ls file1 file2 &> log
。
ls file1 file2 2> error.log 1> access.log
ls file1 file2 &> log
输出重定向有两种方式临时重定向和永久重定向。对于 临时重定向 ,您可以使用>
或者>>
符号。如果您有很多数据需要重定向,您可以使用exec
命令进行永久重定向。
永久重定向并不是真的就一直唯一类型的重定向,可以随时使用exec
命令进行修改。
永久重定向相当于为进程创建一个文件描述符,接下来运行命令的标准输出,标准错误,标准输入都使用同一文件描述符。
例如std.sh
脚本将会重定向exec
命令之后的所有标准输出,也就是echo生成的标准输出。如果运行cat命令查看log文件,我们将看到echo命令的标准输出。
你可以多次使用exec
命令多次重定向不同的文件描述符,例如命令exec 2> error.log
将标准错误重定向到文件error.log
。
std.sh
#!/bin/bash
exec 1> log #永久重定向标准输出
echo "Permanent redirection"
echo "from a shell to a file."
echo "without redirecting every line"
exec 2> error.log #永久重定向标准错误
echo "Script Begining ..."
echo "Redirecting Output"
除了使用exec
命令重定向标准输出,标准错误。你还可以使用exec
命令重定向标准输入。默认的标准输入STDIN
,也就是文件描述符1
,通常是键盘。
命令exec 0< log
将使用log文件作为标准输入STDIN
,而不是默认的键盘。通常Linux系统管理员使用这种技术来读取日志文件进行处理。
stdin.sh
脚本很简单。您应该知道如何使用read 命令获取用户输入。如果将文件重定向到标准输入STDIN
,read命令将尝试读取文件的内容。
stdin.sh
#!/bin/bash
exec 0< testfile
total=1
while read line; do
echo "#$total: $line"
total=$(($total + 1))
done
有时候您可能不想看到任何输出。我们将输出重定向到黑洞,也就是空设备文件/dev/null。这种情况在使用nohup命令启动后台进程时常见。
在使用nohup命令启动后台进程时你可能见过符号2>&1
,但很少使用这种方式2> /dev/null 1> /dev/null
重定向到空设备文件/dev/null
。
其实ls -al file1 file2 2> /dev/null 1> /dev/null
和ls -al file1 file2 > /dev/null 2>&1
是不相等的命令。
2> /dev/null 1> /dev/null
是直接将标准错误重定向到空设备文件,而> /dev/null 2>&1
是将标准错误先重定向到标准输出,然后再重定向到空设备文件。
ls -al file1 file2 2> /dev/null 1> /dev/null
ls -al file1 file2 > /dev/null 2>&1
如果2>&1
是将标准错误信息重定向到标准输出,你可能会想问2>1
结果是什么,我们可以运行命令ls -al file1 file2 2>1
来验证这一点。
运行命令后你可能注意到当前目录存在文件1,运行命令cat 1
你会发现标准错误都写入文件1。
也就是说2>1
会将标准错误重定向到文件1里面,所以2>&1
中的&1
指标准输出。
ls -al file1 file2 2>1
cat 1
ls: cannot access 'file2': No such file or directory
现在您了解标准输入、标准输出、标准错误以及如何重定向它们。
全部0条评论
快来发表一下你的评论吧 !