自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux中的輸入、輸出和錯(cuò)誤重定向

系統(tǒng) Linux
我們都知道 Linux 命令的功能,它接受一個(gè)輸入,然后給你一個(gè)輸出。在這里起作用的包含一些重要的角色,我們今天就來介紹一下這些角色。

如果你熟悉基本的 Linux 命令,還應(yīng)該學(xué)習(xí)輸入輸出重定向的概念。

我們都知道 Linux 命令的功能,它接受一個(gè)輸入,然后給你一個(gè)輸出。在這里起作用的包含一些重要的角色,我們今天就來介紹一下這些角色。

stdin, stdout 和 stderr

當(dāng)你運(yùn)行 Linux 命令時(shí),有三個(gè)數(shù)據(jù)流在其中起作用:

  • stdin:(Standard input,標(biāo)準(zhǔn)輸入)是輸入數(shù)據(jù)的源。默認(rèn)情況下,stdin 是從鍵盤輸入的任何文本,它的流 ID(stream ID) 為 0;
  • stdout:(Standard output,標(biāo)準(zhǔn)輸出)是命令的輸出結(jié)果。默認(rèn)情況下,它會(huì)顯示在屏幕上,它的流 ID(stream ID) 為 1;
  • stderr:(Standard error,標(biāo)準(zhǔn)錯(cuò)誤)是命令產(chǎn)生的錯(cuò)誤消息(如果有)。默認(rèn)情況下,屏幕上也會(huì)顯示 stderr。它的流 ID(stream ID)是2。

這些流包含存儲(chǔ)在內(nèi)存緩沖區(qū)(buffer memory)中的純文本數(shù)據(jù)。

把它想象成一個(gè)水流,你需要水源,比如水龍頭,用管道連接到它,可以將其存儲(chǔ)在水桶(文件)中,也可以給植物澆水(打?。H绻枰?,還可以將其連接到另外一個(gè)水龍頭上,也就是改變水的流向(重定向)。

Linux 中也有這種重定向的概念。你可以將 stdin, stdout 和 stderr 從其原本的目標(biāo),重定向到另一個(gè)文件或命令(甚至是打印機(jī)等外圍設(shè)備)。

接下來我們來介紹一下重定向是如何工作的,以及如何使用它。

輸出重定向

第一種也是最簡單的重定向形式是輸出重定向,也稱為標(biāo)準(zhǔn)輸出重定向。

默認(rèn)情況下,命令的輸出是顯示在屏幕上。比如,我使用 ls 命令列出當(dāng)前目錄下的所有文件:

[gliu@fedora work]$ ls
appstxt new.txt static-ip.txt

通過輸出重定向,可以將輸出重定向到文件。如果此輸出文件不存在,那么 shell 將創(chuàng)建它。

command > file

比如,我們將上述 ls 命令的輸出保存到名為 output.txt 的文本文件中:

[gliu@fedora work]$ ls > output.txt

輸出文件是預(yù)先創(chuàng)建的

那么這個(gè) output.txt 文件的內(nèi)容是什么呢?我們用 cat 命令來看一下:

[gliu@fedora work]$ cat output.txt
appstxt
new.txt
output.txt
static-ip.txt

有沒有注意到里面也包含 output.txt?將輸出重定向輸出到的文件(output.txt)是在運(yùn)行預(yù)期命令之前創(chuàng)建的。為什么呢?因?yàn)樗枰獪?zhǔn)備好輸出的目的地,輸出將被發(fā)送到該目的地。

追加而不是刪除

一個(gè)經(jīng)常被忽略的問題是,如果重定向到一個(gè)已經(jīng)存在的文件,shell 將首先刪除該文件。這意味著輸出文件的現(xiàn)有內(nèi)容將被刪除,并替換為命令的輸出。

如果不想刪除原有的內(nèi)容,而只是追加,那么可以使用 >> 重定向語法:

command >> file

你可以在當(dāng)前的 shell 會(huì)話中禁止刪除,使用 set -C

將輸出重定向到文件,可以將輸出的內(nèi)容保存起來以供將來參考;另外如果輸出的內(nèi)容太多,占用了大篇幅的屏幕時(shí),將內(nèi)容保存到文件,就更方便查看和分析了,這就像收集日志文件一樣。

管道重定向

在介紹 stdin 重定向之前,我們先來了解一下管道重定向,這是更加常見的,我們會(huì)經(jīng)常使用管道重定向。

關(guān)于管道重定向,可以參閱我們先前的文章:Linux 中的管道是什么?管道重定向是如何工作的?

通過管道重定向,可以將命令的標(biāo)準(zhǔn)輸出發(fā)送到另一個(gè)命令的標(biāo)準(zhǔn)輸入。

command 1 | command 2

我們來舉個(gè)例子,如果我們要查看當(dāng)前目錄中文件的數(shù)量,可以使用 ls -1(注意是數(shù)字1,不是字母L)來顯示當(dāng)前目錄中的文件:

[gliu@fedora work]$ ls -1
appstxt
new.txt
output.txt
static-ip.txt

我們知道 wc 命令用于計(jì)算文件中的行數(shù),所以我們可以結(jié)合這個(gè)命令,如下:

[gliu@fedora work]$ ls -1 | wc -l
4

使用管道,兩個(gè)命令共享相同的內(nèi)存緩沖區(qū),第一個(gè)命令的輸出存儲(chǔ)在緩沖區(qū)中,然后該緩沖區(qū)將用作下一個(gè)命令的輸入。

你將看到管道中最后一個(gè)命令的結(jié)果。這一點(diǎn)很明顯,因?yàn)橄惹懊畹?stdout 被重定向到下一個(gè)命令,而不是打印在屏幕上。

管道重定向或管道不限于僅連接兩個(gè)命令,你也可以連接多個(gè)命令,只要一個(gè)命令的輸出可用作下一個(gè)命令輸入。

command_1 | command_2 | command_3 | command_4

請(qǐng)注意,stdout/stdin是一塊數(shù)據(jù),而不是文件名

一些新的Linux用戶在使用重定向時(shí)會(huì)感到困惑,如果命令返回一組文件名作為輸出,則不能將這些文件名用作參數(shù)。

比如,使用 find 命令查找擴(kuò)展名為 .txt 的文件,無法通過管道將查找到的這些文件移動(dòng)到新的目錄,不能這樣操作:

find . -type f -name "*.txt" | mv destination_directory

這就是為什么我們經(jīng)常會(huì)看到 find 命令與 exec 或 xargs 命令組合使用的原因。這些命令可以將大量的文本“文件名”轉(zhuǎn)換為文件名,且可作為參數(shù)傳遞。

find . -type f -name "*.txt" | xargs -t -I{} mv {} ../new_dir

關(guān)于find 與 exec 或 xargs 命令組合使用的相關(guān)內(nèi)容,可參考我們先前的文章:

find 與 exec 命令的結(jié)合,是一個(gè)功能強(qiáng)大的搜索工具

如何在Linux中使用xargs命令

輸入重定向

使用 stdin 重定向可以將文本文件的內(nèi)容傳遞給終端命令:

command < file

但是這種并不常用,因?yàn)榇蠖鄶?shù) Linux 命令都可以接受文件名作為參數(shù),因此通常不需要 stdin 重定向。比如:

head < filename.txt

上面的命令可以直接寫為:head filename.ext(也就是不用重定向符號(hào) <)。

也不是說 stdin 重定向完全沒有用,有些命令是依賴于它的。以 tr 命令為例,這個(gè)命令可以做很多事情,但在下面的例子中,它將輸入文本從小寫轉(zhuǎn)為大寫:

tr a-z A-Z < filename.txt

事實(shí)上,建議在管道上使用標(biāo)準(zhǔn)輸入重定向,以避免不必要地使用 cat 命令。

比如上面的例子,很多人就習(xí)慣使用 cat,然而這里并沒有必要使用cat:

cat filename.txt | tr a-z A-Z

合并重定向

你可以根據(jù)需要組合使用 stdin,stdout 和管道重定向。

比如,下面的命令列出當(dāng)前目錄下所有的 txt 文件,然后統(tǒng)計(jì)一下文件的總數(shù),并將這個(gè)結(jié)果保存到一個(gè)新文件中:

ls *.txt | wc -l > count.txt

錯(cuò)誤重定向

有時(shí)候,當(dāng)你運(yùn)行一些命令或腳本時(shí),會(huì)在屏幕上看到一條錯(cuò)誤信息:

[gliu@fedora work]$ ls -l ffffff > output.txt
ls: cannot access 'ffffff': No such file or directory

在本文的開頭,我們提到過有三種數(shù)據(jù)流,stderr 是其中之一,它默認(rèn)將輸出顯示在屏幕上。

你也可以重定向 stderr。由于它是一個(gè)輸出數(shù)據(jù)流,因此可以使用與標(biāo)準(zhǔn)輸出重定向相同的 > 或 >> 重定向符號(hào)。

但是,當(dāng) stdout 和 stderr 都作為輸出數(shù)據(jù)流時(shí),如何區(qū)分它們呢?通過它們的流 ID(stream ID,也稱為文件描述符)。

Data stream

stream ID

stdin

0

stdout

1

stderror

2

-t

-list

-u

-update

-x

–extract, –get

-j

–bzip2

-z

–gzip, –gunzip, –ungzip

默認(rèn)情況下,當(dāng)你使用輸出重定向符號(hào) > 時(shí),它實(shí)際上是 1 >。換句話說,ID 為 1 的數(shù)據(jù)流是在這里輸出。

所以當(dāng)你要重定向 stderr 時(shí),可以使用它的ID,比如 2> 或者 2>>。這表示輸出重定向用于數(shù)據(jù)流 stderr(ID為2)。

stderr 重定向示例

我們來舉幾個(gè)例子。假如我們只想要保存錯(cuò)誤信息,那么可以這樣:

[gliu@fedora work]$ ls fffff 2> error.txt
[gliu@fedora work]$ cat error.txt
ls: cannot access 'fffff': No such file or directory

這個(gè)很簡單。我們?cè)賮韨€(gè)稍微復(fù)雜一點(diǎn)的(并且很有用的):

[gliu@fedora work]$ ls -l new.txt ffff > output.txt 2> error.txt
[gliu@fedora work]$ cat output.txt
-rw-rw-r-- 1 gliu gliu 0 May 5 10:25 new.txt
[gliu@fedora work]$ cat error.txt
ls: cannot access 'ffff': No such file or directory

在上面的例子中,ls 命令嘗試顯示兩個(gè)文件的信息。其中一個(gè)文件能成功,另一個(gè)會(huì)出錯(cuò)。所以我在這里做的是將 stdout 輸出重定向到 output.txt 文件中,將 stderr 重定向到 error.txt 中(使用 2>)。

此外,我們還可以將 stdout 和 stderr 重定向到同一個(gè)文件,是有辦法做到這一點(diǎn)的。

在下面的例子中,我使用追加模式(append mode)將 stderr 重定向到文件 combined.txt 中(使用 2>>);然后,同樣使用追加模式將標(biāo)準(zhǔn)輸出 stdout 重定向到同一個(gè)文件 combined.txt 中(使用 >>):

[gliu@fedora work]$ ls -l new.txt fff 2>> combined.txt >> combined.txt
[gliu@fedora work]$ cat combined.txt
ls: cannot access 'fff': No such file or directory
-rw-rw-r-- 1 gliu gliu 0 May 5 10:25 new.txt

另一種方法,也是首選的方法,是使用類似于 2>&1 的東西,可以大致的翻譯為“將 stderr 重定向到與 stdout 相同的地址中”。

我們以前面的示例為例,這次使用 2>&1 將 stdout 和 stderr 重定向到同一個(gè)文件:

[gliu@fedora work]$ ls -l new.txt fff > output.txt 2>&1
[gliu@fedora work]$ cat output.txt
ls: cannot access 'fff': No such file or directory
-rw-rw-r-- 1 gliu gliu 0 May 5 10:25 new.txt

在這里需要注意的一點(diǎn)是,不能想當(dāng)然的以為 2>>&1 為追加模式,因?yàn)?2>&1 本身就是追加模式。

此外,你也可以先使用 2>,然后使用 1>&2 將 stdout 重定向到與 stderr 相同的文件上?;旧?,>& 是將一個(gè)輸出數(shù)據(jù)流重定向到另一個(gè)上。

我們來總結(jié)一下

1)有三種數(shù)據(jù)流,其中一個(gè)是輸入數(shù)據(jù)流 stdin(0),兩個(gè)輸出數(shù)據(jù)流為 stdout(1) 和 stderr(2);

2)鍵盤輸入是默認(rèn)的標(biāo)準(zhǔn)輸入設(shè)備,屏幕是默認(rèn)的輸出設(shè)備;

3)輸出重定向使用 > 或者 >>(用于追加模式);

4)輸入重定向使用 <;

5)stderr 可以使用 2> 或者 2>>;

6)stderr 和 stdout 可以組合為:2>&1。

至此我們了解了關(guān)于重定向的相關(guān)知識(shí),那么為了更加深入的學(xué)習(xí),還可以了解一下 tee 命令,該命令可以將數(shù)據(jù)顯示到標(biāo)準(zhǔn)輸出中,同時(shí)保存到文件中。我們稍后會(huì)分享這個(gè)命令的用法。

以上就是本次分享全部內(nèi)容,歡迎討論。

責(zé)任編輯:龐桂玉 來源: TIAP
相關(guān)推薦

2014-09-04 11:39:43

Linux

2022-11-17 08:40:14

Linux輸出錯(cuò)誤重定向

2010-06-23 16:14:52

Linux Bash

2009-12-25 16:21:41

shell命令

2010-03-01 14:45:07

Linux文件重定向

2009-06-30 15:37:27

Servlet和JSP

2020-02-24 11:37:56

Linux重定向管道

2010-12-14 15:07:15

ICMP路由重定向

2010-03-09 16:11:59

Linux重定向

2017-01-19 19:14:20

Linux重定向命令

2010-07-13 14:10:44

ICMP協(xié)議

2020-07-27 07:41:23

Linux重定向數(shù)據(jù)流

2014-08-07 10:23:24

linux重定向

2021-03-28 08:32:58

Java

2022-11-14 15:07:09

Linux管道

2009-06-17 17:13:40

UNIX

2009-06-17 09:11:24

Unix管道重定向

2009-06-25 14:54:22

Servlet轉(zhuǎn)發(fā)Servlet重定向

2011-04-20 10:15:02

Linuxconsole口

2017-01-19 19:24:29

Linux重定向
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)