Linux - 命令重定向

命令重定向, 就是將目前獲得的數據轉移到指定的地方.分爲如下幾種:

>
>>
1>
2>
1>>
2>>
<

1. > 與 >>
先看一個簡單的例子. 若是執行ll指令, 會在屏幕上顯示執行結果:

bash

[root@localhost yuechaotian]# pwd
/home/yuechaotian
[root@localhost yuechaotian]# ll
總用量 52
-r--------  1 root        root           22  9月  4 16:31 adsl賬號.txt
-rw-rw-r--  1 yuechaotian yuechaotian     2 12月 14 10:54 r.log
-rw-rw-r--  1 yuechaotian yuechaotian     0 12月 14 10:20 r.log.r
-rw-rw-r--  1 yuechaotian yuechaotian    24 12月 14 10:20 r.log.w
drwx--x--x  3 root        root         4096 12月  7 14:52 study
drwxrwxrwx  2 yuechaotian yuechaotian  4096 12月 14 10:58 test
-rw-------  1 root        root         5789 12月 12 20:53 tnsnames.ora
-r--------  1 root        root        22528  8月 31 10:26 房屋租賃合同.doc
[root@localhost yuechaotian]# ll test/
總用量 0


若是不想在屏幕上顯示, 而是想把輸出結果直接存儲在指定的文件中, 可使用 > 或 >>

併發

# > 將輸出結果以"覆蓋"的形式存儲在指定的文件中, 若文件不存在則自動建立.
[root@localhost yuechaotian]# ll > test/ll.log
[root@localhost yuechaotian]# cat test/ll.log
總用量 52
-r--------  1 root        root           22  9月  4 16:31 adsl賬號.txt
-rw-rw-r--  1 yuechaotian yuechaotian     2 12月 14 10:54 r.log
-rw-rw-r--  1 yuechaotian yuechaotian     0 12月 14 10:20 r.log.r
-rw-rw-r--  1 yuechaotian yuechaotian    24 12月 14 10:20 r.log.w
drwx--x--x  3 root        root         4096 12月  7 14:52 study
drwxrwxrwx  2 yuechaotian yuechaotian  4096 12月 14 11:01 test
-rw-------  1 root        root         5789 12月 12 20:53 tnsnames.ora
-r--------  1 root        root        22528  8月 31 10:26 房屋租賃合同.doc
# >> 將輸出結果以「追加」的形式存儲在指定的文件中, 若文件不存在則自動建立。
[root@localhost yuechaotian]# ll test/ >> test/ll.log
[root@localhost yuechaotian]# cat test/ll.log
總用量 52
-r--------  1 root        root           22  9月  4 16:31 adsl賬號.txt
-rw-rw-r--  1 yuechaotian yuechaotian     2 12月 14 10:54 r.log
-rw-rw-r--  1 yuechaotian yuechaotian     0 12月 14 10:20 r.log.r
-rw-rw-r--  1 yuechaotian yuechaotian    24 12月 14 10:20 r.log.w
drwx--x--x  3 root        root         4096 12月  7 14:52 study
drwxrwxrwx  2 yuechaotian yuechaotian  4096 12月 14 11:01 test
-rw-------  1 root        root         5789 12月 12 20:53 tnsnames.ora
-r--------  1 root        root        22528  8月 31 10:26 房屋租賃合同.doc
總用量 4
-rw-r--r--  1 root root 569 12月 14 11:01 ll.log


那麼若是指令執行失敗呢? 輸出結果就不會保存到指定文件中:

app

[root@localhost yuechaotian]# ll testx > test/ll.log.2
ls: testx: 沒有那個文件或目錄
[root@localhost yuechaotian]# ll test/
總用量 4
-rw-r--r--  1 root root 631 12月 14 11:03 ll.log
-rw-r--r--  1 root root   0 12月 14 11:08 ll.log.2
[root@localhost yuechaotian]# cat test/ll.log.2
[root@localhost yuechaotian]#


2. 1> 2>
若是須要將輸出的正確結果保存到一個文件中, 輸出的錯誤結果保存到另外一個文件中,能夠藉助 1> 和 2>

dom

[root@localhost yuechaotian]# ll testx/ 1> test/ll.right 2> test/ll.wrong
[root@localhost yuechaotian]# ll test/
總用量 8
-rw-r--r--  1 root root 631 12月 14 11:03 ll.log
-rw-r--r--  1 root root   0 12月 14 11:08 ll.log.2
-rw-r--r--  1 root root   0 12月 14 11:11 ll.right
-rw-r--r--  1 root root  40 12月 14 11:11 ll.wrong
[root@localhost yuechaotian]# cat test/ll.right
[root@localhost yuechaotian]# cat test/ll.wrong
ls: testx/: 沒有那個文件或目錄


Linux是經過什麼來判斷的呢?由於每一個當前指令的執行結果都保存在環境變量「?」中,當指令執行成功時 ?=0,當指令執行失敗時 ?=1。Linux就是經過它來判斷輸出結果保存到哪一個文件中的:

測試

[root@localhost yuechaotian]# ll test/
總用量 8
-rw-r--r--  1 root root 631 12月 14 11:03 ll.log
-rw-r--r--  1 root root   0 12月 14 11:08 ll.log.2
-rw-r--r--  1 root root   0 12月 14 11:11 ll.right
-rw-r--r--  1 root root  40 12月 14 11:11 ll.wrong
[root@localhost yuechaotian]# echo $?
0
[root@localhost yuechaotian]# ll testx/
ls: testx/: 沒有那個文件或目錄
[root@localhost yuechaotian]# echo $?
1


若是想不論指令執行正確與否,都將結果輸出到同一個指定文件中,須要藉助 1> 和 2>&1:

this

[root@localhost yuechaotian]# ll testx/ 1> test/ll.all 2>&1
[root@localhost yuechaotian]# cat test/ll.all
ls: testx/: 沒有那個文件或目錄


若是能夠提早預知錯誤的結果,只想保存正確的輸出結果,而刪除掉錯誤的結果,有什麼好辦法麼?能夠將錯誤的輸出直接保存到「垃圾筒」中,這就藉助到一個設備 /dev/null

spa

[root@localhost yuechaotian]#ll testx/ 1> test/ll.right.only 2>/dev/null


3. 1>> 2>>
一樣地,若是想將正確的輸出結果追加到一個文件中,錯誤的輸出結果追加到另外一個文件中,就須要藉助 1>> 和 2>> 了。它們的使用方法跟 1> 2> 相似,所不一樣的就是執行結果是追加到指定文件中,而不是覆蓋。

orm

[root@localhost test]# cat ll.wrong
ls: testx/: 沒有那個文件或目錄
[root@localhost test]# cat ll.right
[root@localhost test]# cd subtest 1>> ll.right 2>> ll.wrong
[root@localhost test]# cat ll.right
[root@localhost test]# cat ll.wrong
ls: testx/: 沒有那個文件或目錄
-bash: cd: subtest: 沒有那個文件或目錄
[root@localhost test]# ll ../ 1>> ll.right 2>> ll.wrong
[root@localhost test]# cat ll.right
總用量 60
-r--------  1 root        root           22  9月  4 16:31 adsl賬號.txt
-rw-r--r--  1 root        root           62 12月 14 11:02 ll.log
-rw-rw-r--  1 yuechaotian yuechaotian     2 12月 14 10:54 r.log
-rw-rw-r--  1 yuechaotian yuechaotian     0 12月 14 10:20 r.log.r
-rw-rw-r--  1 yuechaotian yuechaotian    24 12月 14 10:20 r.log.w
-rw-r--r--  1 root        root            6 12月 14 11:06 s.log
drwx--x--x  3 root        root         4096 12月  7 14:52 study
drwxrwxrwx  2 yuechaotian yuechaotian  4096 12月 14 11:20 test
-rw-------  1 root        root         5789 12月 12 20:53 tnsnames.ora
-r--------  1 root        root        22528  8月 31 10:26 房屋租賃合同.doc
[root@localhost test]# cat ll.wrong
ls: testx/: 沒有那個文件或目錄
-bash: cd: subtest: 沒有那個文件或目錄


4. 1> 2>> 與 1>> 2>
若是想將正確的輸出和錯誤的輸出都「追加」到同一個文件中,怎麼辦?你想試試 1>> 和 2>>&1 嗎:

token

[root@localhost test]# rm *
[root@localhost test]# echo "right and wrong" 1>> ll.r 2>>&1
-bash: syntax error near unexpected token `&'
[root@localhost test]# ll
總用量 0


是的,沒有 2>>&1 這個語法,但有 2>&1 這個語法,把 1>> 和 2>&1 接合起來看呢:

crontab

[root@localhost test]# echo "right and wrong" 1>> ll.r 2>&1
[root@localhost test]# ll
總用量 4
-rw-r--r--  1 root root 16 12月 14 11:39 ll.r
[root@localhost test]# cat ll.r
right and wrong
[root@localhost test]# echo "right and wrong2" 1>> ll.r 2>&1
[root@localhost test]# cat ll.r
right and wrong
right and wrong2
[root@localhost test]# ll "right and wrong2" 1>> ll.r 2>&1
[root@localhost test]# cat ll.r
right and wrong
right and wrong2
ls: right and wrong2: 沒有那個文件或目錄


咱們看,使用 1>> 和 2>&1 達到了目的。那就是說 1> 和 2>,1>> 和 2>> 並非配對的關係,他們之間應該是能夠交叉使用的。下面測試一下:

[root@localhost test]# pwd
/home/yuechaotian/test
[root@localhost test]# rm *
# 1. 輸出正確則「追加」,輸出錯誤則「覆蓋」
[root@localhost test]# echo "right_append & wrong_cover" 1>> ll.r 2> ll.w
[root@localhost test]# cat ll.r
right_append & wrong_cover
[root@localhost test]# cat ll.w
[root@localhost test]# echo "right_append & wrong_cover2" 1>> ll.r 2> ll.w
[root@localhost test]# cat ll.r
right_append & wrong_cover
right_append & wrong_cover2
[root@localhost test]# cat ll.w
[root@localhost test]# cd "right_append & wrong_cover2" 1>> ll.r 2> ll.w
[root@localhost test]# cat ll.r
right_append & wrong_cover
right_append & wrong_cover2
[root@localhost test]# cat ll.w
-bash: cd: right_append & wrong_cover2: 沒有那個文件或目錄
[root@localhost test]# cd "right_append & wrong_cover" 1>> ll.r 2> ll.w
[root@localhost test]# cat ll.r
right_append & wrong_cover
right_append & wrong_cover2
[root@localhost test]# cat ll.w
-bash: cd: right_append & wrong_cover: 沒有那個文件或目錄
#2. 輸出正確則「覆蓋」,輸出錯誤則「追加」
[root@localhost test]# echo "right_cover & wrong_append" 1> ll.r 2>> ll.w
[root@localhost test]# cat ll.r
right_cover & wrong_append
[root@localhost test]# cat ll.w
-bash: cd: right_append & wrong_cover: 沒有那個文件或目錄
[root@localhost test]# cd "right_cover & wrong_append" 1> ll.r 2>> ll.w
[root@localhost test]# cat ll.r
[root@localhost test]# cat ll.w
-bash: cd: right_append & wrong_cover: 沒有那個文件或目錄
-bash: cd: right_cover & wrong_append: 沒有那個文件或目錄


一個小問題:若是輸出正確則「追加」,輸出錯誤則直接刪除。怎麼實現?

如今有兩種方法了:1>> 2>> /dev/null 和 1>> 2>/dev/null。其實「追加」到垃圾筒與「覆蓋」到垃圾筒效果是同樣的。設備/dev/null就象一個無底洞,扔進去的東西瞬間就消失了。一樣地,也能夠將錯誤的輸出保存起來,而將正確的輸出「扔」到垃圾筒中。

5. <
< 的做用,就是將本來應該由鍵盤輸入的數據經由文件讀入。好比發送郵件,可使用鍵盤輸入郵件內容,也可使用 < 將保存在磁盤中的文件讀出,併發送出去

# 1. 使用鍵盤輸入方式來發送郵件給yuechaotian
[root@localhost test]# mail -s "hi, yuechaotian" yuechaotian
Hi, I'm root.
.
Cc:
[root@localhost test]# su - yuechaotian
[yuechaotian@localhost ~]$
[yuechaotian@localhost ~]$ procmail -v
procmail v3.22 2001/09/10
    Copyright (c) 1990-2001, Stephen R. van den Berg   
    Copyright (c) 1997-2001, Philip A. Guenther        

Submit questions/answers to the procmail-related mailinglist by sending to:
       

And of course, subscription and information requests for this list to:
       

Locking strategies:     dotlocking, fcntl()
Default rcfile:         $HOME/.procmailrc
        It may be writable by your primary group
Your system mailbox:    /var/mail/yuechaotian
[yuechaotian@localhost ~]$ cat /var/mail/yuechaotian
From root@localhost.localdomain  Sun Dec 14 12:10:08 2008
Return-Path:
Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
        by localhost.localdomain (8.13.1/8.13.1) with ESMTP id mBE4A8U0001330
        for ; Sun, 14 Dec 2008 12:10:08 +0800Received: (from root@localhost)
        by localhost.localdomain (8.13.1/8.13.1/Submit) id mBE4A86X001329
        for yuechaotian; Sun, 14 Dec 2008 12:10:08 +0800
Date: Sun, 14 Dec 2008 12:10:08 +0800
From: root
Message-Id: <200812140410.mBE4A86X001329@localhost.localdomain>
To: yuechaotian@localhost.localdomain
Subject: hi, yuechaotian

Hi, I'm root.
# 2. 那好,如今我將郵件內容保存到 mail.txt 中,使用 < 將 mail.txt 中的內容從新發送給yuechaotian
[yuechaotian@localhost ~]$ su - root
Password:
[root@localhost ~]# cd /home/yuechaotian/
[root@localhost yuechaotian]# touch mail.txt
[root@localhost yuechaotian]# echo > mail.txt "Hi, I'm root, I send this mail by using <."
[root@localhost yuechaotian]# cat mail.txt
Hi, I'm root, I send this mail by using <.
[root@localhost yuechaotian]# mail -s "hi, yuechaotian" yuechaotian < mail.txt
[root@localhost yuechaotian]# su - yuechaotian
[yuechaotian@localhost ~]$ cat /var/mail/yuechaotian
From root@localhost.localdomain  Sun Dec 14 12:10:08 2008
Return-Path:
Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
        by localhost.localdomain (8.13.1/8.13.1) with ESMTP id mBE4A8U0001330
        for ; Sun, 14 Dec 2008 12:10:08 +0800Received: (from root@localhost)
        by localhost.localdomain (8.13.1/8.13.1/Submit) id mBE4A86X001329
        for yuechaotian; Sun, 14 Dec 2008 12:10:08 +0800
Date: Sun, 14 Dec 2008 12:10:08 +0800
From: root
Message-Id: <200812140410.mBE4A86X001329@localhost.localdomain>
To: yuechaotian@localhost.localdomain
Subject: hi, yuechaotian

Hi, I'm root.

From root@localhost.localdomain  Sun Dec 14 12:33:12 2008
Return-Path:
Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
        by localhost.localdomain (8.13.1/8.13.1) with ESMTP id mBE4XCun024530
        for ; Sun, 14 Dec 2008 12:33:12 +0800Received: (from root@localhost)
        by localhost.localdomain (8.13.1/8.13.1/Submit) id mBE4XChc024529
        for yuechaotian; Sun, 14 Dec 2008 12:33:12 +0800
Date: Sun, 14 Dec 2008 12:33:12 +0800
From: root
Message-Id: <200812140433.mBE4XChc024529@localhost.localdomain>
To: yuechaotian@localhost.localdomain
Subject: hi, yuechaotian

Hi, I'm root, I send this mail by using <.

[yuechaotian@localhost ~]$

6. 什麼時候使用命令重定向 *當屏幕輸出的信息很重要,咱們須要將它保存起來時; *背景執行中的程序,不但願它干擾屏幕正常的輸出結果時; *一些系統的例行性命令(好比寫在/etc/crontab中的文件)的執行結果,但願它能夠保存下來時; *一些執行命令,咱們已經知道可能的錯誤信息,因此想以 2> /dev/null 將它丟掉時; *錯誤信息與正確欣喜須要分別輸出時; *其它須要使用命令重定向的狀況時。

相關文章
相關標籤/搜索