Linux中的输入,输出和错误重定向
如果我们熟悉基本的Linux命令,我们还应该了解输入输出重定向的概念。
Stdin,stdout和stderr
运行Linux命令时,有三个数据流播放其中部分:
- 标准输入(STDIN)是输入数据的源。
默认情况下,stdin是从键盘输入的任何文本。它的流ID是0。
- 标准输出(stdout)是命令的结果。
默认情况下,它显示在屏幕上。它的流ID是1.
- 标准错误(stderr)是命令生成的错误消息(如果有的话)。
默认情况下,STDEDR也会显示在屏幕上。它的流ID是2.
这些流包含纯文本中的数据在被叫缓冲存储器中。
把它想象成水流。
你需要一个水的来源,例如水龙头。
我们将管道连接到它,我们可以将其存放在桶(文件)或者水中植物(打印它)。
如果需要,我们还可以将其连接到另一个水龙头。
基本上,你正在重定向水。
Linux还具有这种重定向的概念,在那里我们可以将STDIN,STDOUT和STDEDR从其平常的目的地重定向到另一个文件或者命令(甚至是打印机等外围设备)。
让我展示重定向是如何运作的以及如何使用它。
输出重定向
第一种和最简单的重定向形式是输出重定向也称为STDOUT重定向。
我们已经知道,默认情况下,屏幕上会显示命令的输出。
例如,我使用ls命令列出所有文件,这是我得到的输出:
Hyman@theitroad:~$ls appstxt new.txt static-ip.txt
使用输出重定向,可以将输出重定向到文件。
如果此输出文件不存在,则shell将创建它。
command > file
例如,让我将ls命令的输出保存到名为contance.txt的文件:
Hyman@theitroad:~$ls > output.txt
事先创建输出文件
我们认为此输出文件的内容应该是什么?
让我用CAT命令向我们展示一个惊喜:
Hyman@theitroad:~$cat output.txt appstxt new.txt output.txt static-ip.txt
你注意到那里包含output.txt吗?
我故意选择这个例子来告诉你这个。
在运行预期命令之前创建重定向的输出文件。
为什么?
因为它需要使输出目的地准备好输出输出。
添加而不是Clobber
一个经常忽略的问题是,如果我们重定向到已经存在的文件,则shell将首先删除(clobber)文件。
这意味着将删除输出文件的现有内容并由命令的输出替换。
我们可以使用>>重定向语法追加,而不是覆盖它。
command >> file
提示:我们可以使用以下方法禁止在当前shell会话中进行Clobbering:set -c
为什么你会重定向stdout?
我们可以将输出存储以供将来参考并稍后分析。
当命令输出太大时,它会特别有用,它需要所有的屏幕。
这就像收集日志。
管道重定向
在看到STDIN重定向之前,我们应该了解管道重定向。
这更为常见,可能你会使用它很多。
通过管道重定向,我们将命令的标准输出发送到另一个命令的标准输入。
command 1 | command 2
让我向你展示一个实际的例子。
说,我们希望计算当前目录中的可见文件的数量。
我们可以使用LS -1(它是数字,而不是字母L)来显示当前目录中的文件:
Hyman@theitroad:~$ls -1 appstxt new.txt output.txt static-ip.txt
我们可能已经知道WC命令用于计数文件中的行数。
如果将这两个命令与管道组合,那就是你得到的:
Hyman@theitroad:~$ls -1 | wc -l 4
使用管道,两个命令共享相同的内存缓冲区。
第一个命令的输出存储在缓冲区中,然后将相同的缓冲区用作下一个命令的输入。
我们将看到管道中最后一个命令的结果。
这很明显,因为早期命令的STDOUT被馈送到下一个命令而不是进入屏幕。
管道重定向或者管道不仅限于连接两个命令。
只要一个命令的输出可以用作下一个命令的输入,我们可以连接更多命令。
command_1 | command_2 | command_3 | command_4
记住stdout/stdin是一个块的数据,而不是文件名
一些新的Linux用户在使用重定向时会变得混淆。
如果命令返回一堆文件名作为输出,则无法使用这些文件名作为参数。
例如,如果我们使用Find命令查找以.txt结尾的所有文件,则无法通过管道将找到的文件移动到新目录,而不是直接如下:
find . -type f -name "*.txt" | mv destination_directory
这就是为什么你经常看到与exec或者xargs命令共轭使用的查找命令。
这些特殊命令将具有束文件名的文本转换为filename',可以作为参数传递。
find . -type f -name "*.txt" | xargs -t -I{} mv {} ../new_dir
输入重定向
我们可以使用STDIN重定向将文本文件的内容传递给这样的命令:
command < file
你不会看到stdin被使用了很多。
这是因为大多数Linux命令接受文件名作为参数,因此通常不需要stdin重定向。
参见这一点:
head < filename.txt
上面的命令可能只是头文件名.txt(没有<)。
这不是Stdin重定向完全没用。
有些命令依赖它。
拍摄例如TR命令。
此命令可以执行很多但在下面的示例中,它将输入文本从较低到大写转换为:
tr a-z A-Z < filename.txt
事实上,使用STDIN是专门用于避免CAT命令的不必要的使用。
例如,许多人将使用上面的例子与CAT,然后使用TR。
坦率地说,这里不需要使用cat 。
cat filename.txt | tr a-z A-Z
结合重定向
我们可以根据需要组合STDIN,STDOUT和管道重定向。
例如,下面的命令列出了当前目录中的所有.txt文件,然后对这些.txt文件进行计数并将输出保存到新文件。
ls *.txt | wc -l > count.txt
错误重定向
有时,当我们运行一些命令或者脚本时,我们会看到它在屏幕上显示错误消息。
Hyman@theitroad:~$ls -l ffffff > output.txt ls: cannot access 'ffffff': No such file or directory
在本文的开头,我提到有三个数据流且STDERR是默认情况下在屏幕上显示的输出数据流之一。
我们也可以将STDERR重定向。
由于它是一个输出数据流,我们可以使用我们用于STDOUT重定向的相同>或者>>重定向符号。
但是,当它们都是输出数据流时,我们如何区分STDOUT和STDERR?
通过他们的流ID(也称为文件描述符)。
|数据流|.流ID |
| --- - | --- |
| stdin | 0 |
| stdout | 1 |
| stderr | 2 |
| -T,| -list|
| -u,| -Update |
| -x,| -extract, -get |
| -J,| -bzip2 |
| -z,| -gzip,-gunzip,-ungzip |
默认情况下,使用输出重定向符号>时,它实际上意味着1>。
用文字说,我们正在此处在此处输出具有ID 1的数据流。
当我们必须重定向STDERR时,我们可以使用其ID,如2>或者2 >>。
这表示输出重定向是用于数据流STDERR(ID 2)。
STDERR重定向示例
让我用一些例子向我们展示。
假设我们只想保存错误,我们可以使用这样的内容:
Hyman@theitroad:~$ls fffff 2> error.txt Hyman@theitroad:~$cat error.txt ls: cannot access 'fffff': No such file or directory
那很简单。
让我们稍微复杂(有用):
Hyman@theitroad:~$ls -l new.txt ffff > output.txt 2> error.txt Hyman@theitroad:~$cat output.txt -rw-rw-r-- 1 igi igi 0 Jan 5 10:25 new.txt Hyman@theitroad:~$cat error.txt ls: cannot access 'ffff': No such file or directory
在上面的示例中,LS命令尝试显示两个文件。
对于一个文件,它获得了成功,另一个文件,它会出错。
所以我在这里所做的是将stdout重定向到out.txt(with>)和stderr到错误.txt(有2个>)。
我们还可以将stdout和stderr重定向到同一文件。
有办法做到这一点。
在下面的示例中,我首先将stderr(用2 >>)发送到Comply.txt文件中。
然后,STDOUT(用>>)以添加模式发送到同一文件。
Hyman@theitroad:~$ls -l new.txt fff 2>> combined.txt >> combined.txt Hyman@theitroad:~$cat combined.txt ls: cannot access 'fff': No such file or directory -rw-rw-r-- 1 igi igi 0 Jan 5 10:25 new.txt
另一种方式,这是首选的方式,是使用类似于2>&1的东西。
这可以大致翻译成"将stderr重定向到与stdout相同的地址"。
让我们参加上一个例子,这次使用2>&1将两个stdout和stderr重定向到同一文件。
Hyman@theitroad:~$ls -l new.txt fff > output.txt 2>&1 Hyman@theitroad:~$cat output.txt ls: cannot access 'fff': No such file or directory -rw-rw-r-- 1 igi igi 0 Jan 5 10:25 new.txt
请记住,我们不能使用2 >>&1在添加模式下使用它。
2>&1已经进入了添加模式。
我们也可以使用2>首先使用1>&2将stdout重定向到与stderr相同的文件。
基本上,它是">&",它将一个输出数据流重定向到另一个。
概括
- 有三个数据流。一个输入,stdin(0)和两个输出数据流stdout(1)和stderr(2)。
- 键盘是默认的STDIN设备,屏幕是默认输出设备。
- 输出重定向用于>或者>>(用于添加模式)。
- 输入重定向用于<。
- 使用2 >>>可以重定向STDERR。
- 可以使用2> 1组合STDEDR和STDOUT。
由于我们正在学习重定向,我们还应该了解TEE命令。
此命令使我们可以显示标准输出并同时保存到文件。