shell 中的<,<<,>,>>


相信熟悉linux的童鞋不會對這四個符合陌生,shell腳本的文件流有時候真的挺容易搞暈人的,下面我們一起了解一下吧

參考鏈接:http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html

文件描述符

linux啟動后,會默認打開3個文件描述符,分別是:標准輸入standard input 0,正確輸出standard output 1,錯誤輸出:error output 2

以后打開文件后。新增文件綁定描述符 可以依次增加。 一條shell命令執行,都會繼承父進程的文件描述符。因此,所有運行的shell命令,都會有默認3個文件描述符。

linux shell下常用輸入輸出操作符是:

1.  標准輸入   (stdin) :代碼為 0 ,使用 < 或 << ; /dev/stdin -> /proc/self/fd/0   0代表:/dev/stdin 
2.  標准輸出   (stdout):代碼為 1 ,使用 > 或 >> ; /dev/stdout -> /proc/self/fd/1  1代表:/dev/stdout
3.  標准錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>> ; /dev/stderr -> /proc/self/fd/2 2代表:/dev/stderr

>,>>

輸出重定向:表示把將輸出重定向到屏幕或者設備或者文件

下面我們直接看一些例子吧

qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1
ls: 無法訪問t.txt1: 沒有那個文件或目錄
t.txt
# 正確輸出和錯誤輸出都顯示在屏幕上
# 我們試着把正確輸出重定向到suc.txt(success),可以看到屏幕輸出上只有錯誤輸出了,
#從這里也可以看出,默認的正確輸出(代碼為1,)是可以忽略不寫的
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 >suc.txt
ls: 無法訪問t.txt1: 沒有那個文件或目錄
qiweijie@qiweijie:~/study_shell$ cat suc.txt 
t.txt
# 正確輸出和錯誤輸出分別輸出到不同的文件
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>suc.txt 2>err.txt
qiweijie@qiweijie:~/study_shell$ cat suc.txt err.txt 
t.txt
ls: 無法訪問t.txt1: 沒有那個文件或目錄
# >> 這樣寫表示追加到文件
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>>suc.txt 2>>err.txt
qiweijie@qiweijie:~/study_shell$ cat suc.txt err.txt 
t.txt
t.txt
ls: 無法訪問t.txt1: 沒有那個文件或目錄
ls: 無法訪問t.txt1: 沒有那個文件或目錄
# &[-,1,2] 分別表示關閉對應的標識,正確輸出,錯誤輸出
# 關閉錯誤輸出
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 2>&-
t.txt
# 錯誤輸出重定向到/dev/null
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 2>/dev/null
t.txt
# 錯誤輸出重定向到到文件
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 2>err1.txt
t.txt
# 關閉正確輸出和錯誤輸出
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>&- 2>&-
# 都輸出到/dev/null
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>/dev/null 2>/dev/null 
# 把錯誤輸出重定向到正確輸出,正確輸出重定向到/dev/null
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 1>/dev/null 2>&1 
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 >/dev/null 2>&1 
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 >ttt.txt 2>&1 
qiweijie@qiweijie:~/study_shell$ cat ttt.txt 
ls: 無法訪問t.txt1: 沒有那個文件或目錄
t.txt
# &代表所有輸出
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 &>/dev/null
qiweijie@qiweijie:~/study_shell$ ls t.txt t.txt1 &>te.txt
qiweijie@qiweijie:~/study_shell$ cat te.txt 
ls: 無法訪問t.txt1: 沒有那個文件或目錄
t.txt

輸入重定向<,<<

也是直接來看一些例子吧

# cat命令表示從屏幕獲取輸入,然后輸出
qiweijie@qiweijie:~/study_shell$ cat
sadf
sadf
# 最簡單的例子,從屏幕獲取輸入,然后重定向給qwj(這里用到是的是輸出重定向
qiweijie@qiweijie:~/study_shell$ cat > qwj
qiweijie shi 2B
qiweijie@qiweijie:~/study_shell$ cat qwj 
qiweijie shi 2B
#這里首先是從文件qwj獲取輸入給cat,然后cat輸入重定向給qwj1
qiweijie@qiweijie:~/study_shell$ cat > qwj1 <qwj 
qiweijie@qiweijie:~/study_shell$ cat qwj1
qiweijie shi 2B
# << 兩個小於號連在一起表示接受一個輸入結束的標識,當輸入這個標識是結束輸入
qiweijie@qiweijie:~/study_shell$ cat > qq << eof
> q
> w
> j
> eof
qiweijie@qiweijie:~/study_shell$ cat qq
q
w
j
qiweijie@qiweijie:~/study_shell$ cat > qqq << e
> q
> w
> e
qiweijie@qiweijie:~/study_shell$ cat qqq
q
w
qiweijie@qiweijie:~/study_shell$

exec綁定重定向

# 綁定新的文件描述符之前的狀態
qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd
0  1  2  3
# 綁定一個新的文件描述符6,並且綁定標准輸出(相當於給標准輸出保存一個臨時copy)
qiweijie@qiweijie:~/study_shell$ exec 6>&1
qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd
0  1  2  3  6
# 綁定標准輸出給suc.txt
qiweijie@qiweijie:~/study_shell$ exec 1>suc.txt 
# 發現標准輸出都沒有了啊
qiweijie@qiweijie:~/study_shell$ ls -al
# 儼然發現suc.txt已經是輸出文件
qiweijie@qiweijie:~/study_shell$ cat suc.txt 
cat: suc.txt:輸入文件是輸出文件
qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd
# 把標准輸出綁定回來
qiweijie@qiweijie:~/study_shell$ exec 1>&6
qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd
0  1  2  3  6
# 關閉自定義的文件描述符
qiweijie@qiweijie:~/study_shell$ exec 6>&-
qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd
0  1  2  3
qiweijie@qiweijie:~/study_shell$ cat suc.txt 
總用量 128
drwxrwxr-x  2 qiweijie qiweijie  4096 11月 24 10:50 .
drwxr-xr-x 34 qiweijie qiweijie  4096 11月 24 10:06 ..
-rw-rw-r--  1 qiweijie qiweijie    61 11月 18 14:19 atlga.xml
-rw-rw-r--  1 qiweijie qiweijie    35 11月 18 14:16 atlga.xml.old
-rw-rw-r--  1 qiweijie qiweijie    13 11月 17 16:17 dos-file.txt
-rw-rw-r--  1 qiweijie qiweijie    52 11月 24 10:11 err1.txt
-rw-rw-r--  1 qiweijie qiweijie   104 11月 24 10:09 err.txt
-rw-rw-r--  1 qiweijie qiweijie    41 11月 18 14:20 example.txt
-rwxrwxr-x  1 qiweijie qiweijie    94 11月 17 16:56 finduser
-rw-rw-r--  1 qiweijie qiweijie     0 11月 24 10:50 g
-rw-rw-r--  1 qiweijie qiweijie   324 11月 18 14:57 merge-sales.sh
-rw-rw-r--  1 qiweijie qiweijie   271 11月 18 17:08 my-friends
-rw-rw-r--  1 qiweijie qiweijie   140 11月 23 17:43 my-friends.sh
-rwxrwxr-x  1 qiweijie qiweijie   141 11月 17 16:34 nusers
-rw-rw-r--  1 qiweijie qiweijie  1958 11月 18 13:54 passwd.txt
-rw-rw-r--  1 qiweijie qiweijie     6 11月 24 10:48 qq
-rw-rw-r--  1 qiweijie qiweijie     4 11月 24 10:49 qqq
-rw-rw-r--  1 qiweijie qiweijie    35 11月 18 14:54 quotas
-rw-rw-r--  1 qiweijie qiweijie    16 11月 24 10:46 qwj
-rw-rw-r--  1 qiweijie qiweijie    16 11月 24 10:47 qwj1
-rw-rw-r--  1 qiweijie qiweijie    39 11月 18 14:53 sales
-rw-rw-r--  1 qiweijie qiweijie     0 11月 24 11:00 suc.txt
-rw-rw-r--  1 qiweijie qiweijie    58 11月 24 10:40 te.txt
-rwxrwxr-x  1 qiweijie qiweijie    55 11月 17 17:02 trace1.sh
-rw-rw-r--  1 qiweijie qiweijie    58 11月 24 10:31 ttt.txt
-rw-rw-r--  1 qiweijie qiweijie 23733 11月 18 15:52 t.txt
-rw-rw-r--  1 qiweijie qiweijie    14 11月 17 16:18 unix-file.txt
-rw-rw-r--  1 qiweijie qiweijie    13 11月 17 16:20 unix.txt
-rw-rw-r--  1 qiweijie qiweijie    25 11月 17 16:15 UN工x-file.txt
0
1
2
3
6
# 如果直接把標准輸出綁定到文件,那么問題就是,你再也變不回來了
qiweijie@qiweijie:~/study_shell$ exec 1>suc.txt 
qiweijie@qiweijie:~/study_shell$ cat suc.txt 
cat: suc.txt:輸入文件是輸出文件
qiweijie@qiweijie:~/study_shell$ exec 1>&-
qiweijie@qiweijie:~/study_shell$ cat suc.txt 
cat: 標准輸出: 錯誤的文件描述符
qiweijie@qiweijie:~/study_shell$ ls /proc/self/fd
ls: 寫入錯誤: 錯誤的文件描述符
qiweijie@qiweijie:~/study_shell$ 

相信通過這些例子,大家對文件描述符和<,<<,>,>>這四個符號應該有一定的印象了吧

 如果定界符以任何一種形式的引號括起來, Shell 便不會處理輸入的內文:

qiweijie@qiweijie:~/study_shell$ cat << 'e'of > echo $file > eof echo $file qiweijie@qiweijie:~/study_shell$ cat << eof > echo $file > eof echo nusers qiweijie@qiweijie:~/study_shell$ 

 以<>打開一個文件作為輸入與輸出之用

警告<>最初是出現在最早的 V7 Bourne Shell 上,不過並沒有形成文檔,且經驗告訴我們,在
很多環境下,它的運行會有點問題。基於此,它並未被大家廣泛了解或使用。雖然它已在
1992 年的 POSIX 標准中標准化,但很多系統里的 /bin/sh 並不支持它。因此如果你對程
序可移植性的要求很高,最好避免使用。

qiweijie@qiweijie:~/study_shell$ (cd test/) ;pwd
/home/qiweijie/study_shell
qiweijie@qiweijie:~/study_shell$ { cd test/ ;} ;pwd
/home/qiweijie/study_shell/test

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM