Linux - 命令重定向
命令重定向, 就是將目前得到的資料轉移到指定的地方.分為以下幾種:
>
>>
1>
2>
1>>
2>>
<
1. > 與 >>
先看一個簡單的例子. 如果執行ll指令, 會在螢幕上顯示執行結果:
[[email protected] yuechaotian]# pwd /home/yuechaotian [[email protected] 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 [ 總用量 0 |
如果不想在螢幕上顯示, 而是想把輸出結果直接儲存在指定的檔案中, 可以使用 > 或 >>
# > 將輸出結果以"覆蓋"的形式儲存在指定的檔案中, 若檔案不存在則自動建立. [[email protected] yuechaotian]# ll > test/ll.log [[email protected] 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 # >> 將輸出結果以“追加”的形式儲存在指定的檔案中, 若檔案不存在則自動建立。 [ [[email protected] 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 |
那麼如果指令執行失敗呢? 輸出結果就不會儲存到指定檔案中:
[[email protected] yuechaotian]# ll testx > test/ll.log.2 ls: testx: 沒有那個檔案或目錄 [[email protected] 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 [[email protected] yuechaotian]# cat test/ll.log.2 [[email protected] yuechaotian]# |
2. 1> 2>
如果需要將輸出的正確結果儲存到一個檔案中, 輸出的錯誤結果儲存到另一個檔案中,可以藉助 1> 和 2>
[[email protected] yuechaotian]# ll testx/ 1> test/ll.right 2> test/ll.wrong [[email protected] 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 [[email protected] yuechaotian]# cat test/ll.right [[email protected] yuechaotian]# cat test/ll.wrong ls: testx/: 沒有那個檔案或目錄 |
Linux是通過什麼來判斷的呢?因為每個當前指令的執行結果都儲存在環境變數“?”中,當指令執行成功時 ?=0,當指令執行失敗時 ?=1。Linux就是通過它來判斷輸出結果儲存到哪個檔案中的:
[[email protected] 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 [[email protected] yuechaotian]# echo $? 0 [[email protected] yuechaotian]# ll testx/ ls: testx/: 沒有那個檔案或目錄 [[email protected] yuechaotian]# echo $? 1 |
如果想不論指令執行正確與否,都將結果輸出到同一個指定檔案中,需要藉助 1> 和 2>&1:
[[email protected] yuechaotian]# ll testx/ 1> test/ll.all 2>&1 [[email protected] yuechaotian]# cat test/ll.all ls: testx/: 沒有那個檔案或目錄 |
如果可以提前預知錯誤的結果,只想儲存正確的輸出結果,而刪除掉錯誤的結果,有什麼好辦法麼?可以將錯誤的輸出直接儲存到“垃圾筒”中,這就藉助到一個裝置 /dev/null
[[email protected] yuechaotian]#ll testx/ 1> test/ll.right.only 2>/dev/null |
3. 1>> 2>>
同樣地,如果想將正確的輸出結果追加到一個檔案中,錯誤的輸出結果追加到另一個檔案中,就需要藉助 1>> 和 2>> 了。它們的使用方法跟 1> 2> 類似,所不同的就是執行結果是追加到指定檔案中,而不是覆蓋。
[[email protected] test]# cat ll.wrong ls: testx/: 沒有那個檔案或目錄 [[email protected] test]# cat ll.right [[email protected] test]# cd subtest 1>> ll.right 2>> ll.wrong [[email protected] test]# cat ll.right [[email protected] test]# cat ll.wrong ls: testx/: 沒有那個檔案或目錄 -bash: cd: subtest: 沒有那個檔案或目錄 [[email protected] test]# ll ../ 1>> ll.right 2>> ll.wrong [[email protected] 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 [[email protected] test]# cat ll.wrong ls: testx/: 沒有那個檔案或目錄 -bash: cd: subtest: 沒有那個檔案或目錄 |
4. 1> 2>> 與 1>> 2>
如果想將正確的輸出和錯誤的輸出都“追加”到同一個檔案中,怎麼辦?你想試試 1>> 和 2>>&1 嗎:
[[email protected] test]# rm * [[email protected] test]# echo "right and wrong" 1>> ll.r 2>>&1 -bash: syntax error near unexpected token `&' [[email protected] test]# ll 總用量 0 |
是的,沒有 2>>&1 這個語法,但有 2>&1 這個語法,把 1>> 和 2>&1 接合起來看呢:
[[email protected] test]# echo "right and wrong" 1>> ll.r 2>&1 [[email protected] test]# ll 總用量 4 -rw-r--r-- 1 root root 16 12月 14 11:39 ll.r [[email protected] test]# cat ll.r right and wrong [[email protected] test]# echo "right and wrong2" 1>> ll.r 2>&1 [[email protected] test]# cat ll.r right and wrong right and wrong2 [[email protected] test]# ll "right and wrong2" 1>> ll.r 2>&1 [[email protected] test]# cat ll.r right and wrong right and wrong2 ls: right and wrong2: 沒有那個檔案或目錄 |
我們看,使用 1>> 和 2>&1 達到了目的。那就是說 1> 和 2>,1>> 和 2>> 並不是配對的關係,他們之間應該是可以交叉使用的。下面測試一下:
[[email protected] test]# pwd /home/yuechaotian/test [[email protected] test]# rm * # 1. 輸出正確則“追加”,輸出錯誤則“覆蓋” [[email protected] test]# echo "right_append & wrong_cover" 1>> ll.r 2> ll.w [[email protected] test]# cat ll.r right_append & wrong_cover [[email protected] test]# cat ll.w [[email protected] test]# echo "right_append & wrong_cover2" 1>> ll.r 2> ll.w [[email protected] test]# cat ll.r right_append & wrong_cover right_append & wrong_cover2 [[email protected] test]# cat ll.w [[email protected] test]# cd "right_append & wrong_cover2" 1>> ll.r 2> ll.w [[email protected] test]# cat ll.r right_append & wrong_cover right_append & wrong_cover2 [[email protected] test]# cat ll.w -bash: cd: right_append & wrong_cover2: 沒有那個檔案或目錄 [[email protected] test]# cd "right_append & wrong_cover" 1>> ll.r 2> ll.w [[email protected] test]# cat ll.r right_append & wrong_cover right_append & wrong_cover2 [[email protected] test]# cat ll.w -bash: cd: right_append & wrong_cover: 沒有那個檔案或目錄 #2. 輸出正確則“覆蓋”,輸出錯誤則“追加” [[email protected] test]# echo "right_cover & wrong_append" 1> ll.r 2>> ll.w [[email protected] test]# cat ll.r right_cover & wrong_append [[email protected] test]# cat ll.w -bash: cd: right_append & wrong_cover: 沒有那個檔案或目錄 [[email protected] test]# cd "right_cover & wrong_append" 1> ll.r 2>> ll.w [[email protected] test]# cat ll.r [[email protected] 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 [[email protected] test]# mail -s "hi, yuechaotian" yuechaotian Hi, I'm root. . Cc: [[email protected] test]# su - yuechaotian [[email protected] ~]$ [[email protected] ~]$ 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 [[email protected] ~]$ cat /var/mail/yuechaotian From [email protected] 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 [email protected]) 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: <[email protected]> To: [email protected] Subject: hi, yuechaotian Hi, I'm root. # 2. 那好,現在我將郵件內容儲存到 mail.txt 中,使用 < 將 mail.txt 中的內容重新發送給yuechaotian [[email protected] ~]$ su - root Password: [[email protected] ~]# cd /home/yuechaotian/ [[email protected] yuechaotian]# touch mail.txt [[email protected] yuechaotian]# echo > mail.txt "Hi, I'm root, I send this mail by using <." [[email protected] yuechaotian]# cat mail.txt Hi, I'm root, I send this mail by using <. [[email protected] yuechaotian]# mail -s "hi, yuechaotian" yuechaotian < mail.txt [[email protected] yuechaotian]# su - yuechaotian [[email protected] ~]$ cat /var/mail/yuechaotian From [email protected] 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 [email protected]) 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: <[email protected]> To: [email protected] Subject: hi, yuechaotian Hi, I'm root. From [email protected] 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 [email protected]) 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: <[email protected]> To: [email protected] Subject: hi, yuechaotian Hi, I'm root, I send this mail by using <. [[email protected] ~]$ |
6. 何時使用命令重定向
*當螢幕輸出的資訊很重要,我們需要將它儲存起來時;
*背景執行中的程式,不希望它干擾螢幕正常的輸出結果時;
*一些系統的例行性命令(比如寫在/etc/crontab中的檔案)的執行結果,希望它可以儲存下來時;
*一些執行命令,我們已經知道可能的錯誤資訊,所以想以 2> /dev/null 將它丟掉時;
*錯誤資訊與正確欣喜需要分別輸出時;
*其它需要使用命令重定向的情況時。