免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
I/O重定向 詳解及例子

1、基本概念
a
I/O重定向通常與 FD有關(guān),shellFD通常為10個,即 09;
b
、常用FD3個,為0stdin,標準輸入)、1stdout,標準輸出)、2stderr
標準錯誤輸出),默認與keyboard、monitor、monitor有關(guān);
c
、用 < 來改變讀進的數(shù)據(jù)信道(stdin),使之從指定的檔案讀進;
d
、用 > 來改變送出的數(shù)據(jù)信道(stdout, stderr),使之輸出到指定的檔案;
e
、0 < 的默認值,因此 < 0<是一樣的;同理,> 1> 是一樣的;
f
、在IO重定向 中,stdout stderr 的管道會先準備好,才會從 stdin 讀進資料;
g
、管道“|”(pipe line):上一個命令的 stdout 接到下一個命令的 stdin;
h
、tee 命令是在不影響原本 I/O 的情況下,將 stdout 復(fù)制一份到檔案去;
i
、bashksh)執(zhí)行命令的過程:分析命令-變量求值-命令替代(``$( ))-重
定向-通配符展開-確定路徑-執(zhí)行命令;
j
、( ) command group 置于 sub-shell 去執(zhí)行,也稱 nested sub-shell,它有
一點非常重要的特性是:繼承父shellStandard input, output, and error plus any
other open file descriptors
。
k
、exec 命令:常用來替代當前 shell 并重新啟動一個 shell,換句話說,并沒有啟
動子 shell。使用這一命令時任何現(xiàn)有環(huán)境都將會被清除,。exec 在對文件描述符進行
操作的時候,也只有在這時,exec 不會覆蓋你當前的 shell 環(huán)境。


2
、基本IO
cmd > file
stdout 重定向到 file 文件中
cmd >> file
stdout 重定向到 file 文件中(追加)
cmd 1> fiel
stdout 重定向到 file 文件中
cmd > file 2>&1
stdout stderr 一起重定向到 file 文件中
cmd 2> file
stderr 重定向到 file 文件中
cmd 2>> file
stderr 重定向到 file 文件中(追加)
cmd >> file 2>&1
stderr stderr 一起重定向到 file 文件中
cmd < file >file2 cmd
命令以 file 文件作為 stdin,以 file2
件作為 stdout
cat <>file
以讀寫的方式打開 file
cmd < file cmd
命令以 file 文件作為 stdin
cmd << delimiter Here document
,從 stdin 中讀入,直至遇到
delimiter
分界符


3
、進階IO
>&n
使用系統(tǒng)調(diào)用 dup (2) 復(fù)制文件描述符 n 并把結(jié)果用作標準輸出
<&n
標準輸入復(fù)制自文件描述符 n
<&-
關(guān)閉標準輸入(鍵盤)
>&-
關(guān)閉標準輸出
n<&-
表示將 n 號輸入關(guān)閉
n>&-
表示將 n 號輸出關(guān)閉
上述所有形式都可以前導(dǎo)一個數(shù)字,此時建立的文件描述符由這個數(shù)字指定而不是缺省
0 1。如:
... 2>file
運行一個命令并把錯誤輸出(文件描述符 2)定向到 file。
... 2>&1
運行一個命令并把它的標準輸出和輸出合并。(嚴格的說是
通過復(fù)制文件描述符 1 來建立文件描述符 2 ,但效果通常是合并了兩個流。)

2>&1
說明:2>&1 也就是 FD2FD1 ,這里并不是說FD2 的值 等于FD1的值,因為 >
是改變送出的數(shù)據(jù)信道,通俗的說是:把stderr并到stdout。
但使用類似 cmd 1>&3 這樣的形式時,原理相同,但往往不同于 2>&1 1>&2 通常
用來合并的作用。

注意:普通cmd命令的cmd n>&n exec n>&n 是有區(qū)別的。

exec 0<infilename #
打開文件infilename作為 stdin
exec 1>outfilename #
打開文件outfilename作為stdout
exec 2>errfilename #
打開文件 errfilename作為 stderr
exec 0<&- #
關(guān)閉 FD0
exec 1>&- #
關(guān)閉 FD1
exec 5>&- #
關(guān)閉 FD5

問:
如果關(guān)閉了 FD0FD1、FD2,其后果是什么?
恢復(fù) FD0FD1、FD2 關(guān)閉FD0FD1、FD2 有什么區(qū)別?代碼分別是什么?
打開了FD3FD9,我們用完之后,你覺得是將他們關(guān)閉還是恢復(fù)?


下面是提示(例子來源于CU):
exec 6>&2 2>ver # FD2(
本來往monitor送的) 定向到文件ver
command >>dev/null & #
丟棄FD1(stdout)
exec 2>&6 #
恢復(fù) FD2


4
、簡單舉例(其中 yes.txt存在,no.txt不存在)
a
stdout stderr 都通過管道送給egrep了:
(ls yes.txt 2>&1;ls no.txt 2>&1) 2>&1|egrep \* >file
(ls yes.txt;ls no.txt) 2>&1|egrep \* >file

###
這個例子就是讓大家:理解 命令執(zhí)行順序 管道“|”
在命令執(zhí)行前,先要進行重定向的處理,并將把 nested sub-shell stdout 接到
egrep
命令的 stdin
nested sub-shell
,在 ( ) 中的兩個命令可以看作一個命令。其 stdout(FD1)
“|” 作為 egrep stdin,再加上 2>&1 時,初始 stdout stderr 都往管道
“|”
送。
###

b
、沒有任何東西通過管道送給egrep,全部送往monitor
(ls yes.txt 2>&1;ls no.txt 2>&1) >&2|egrep \* >file
雖然在()里面將 FD2轉(zhuǎn)往FD1,但在()外,遇到 >&2 ,結(jié)果所有的都送到monitor


5
、中階例子(其中 you 這個文件是存在的,no wu 這兩個文件不存在)
r2007
兄的:http://bbs.chinaunix.net/forum/view...1848&show_type=
new&sid=cf30398c911e0d2b16313c6922123f67

條件:stderr通過管道送給egrep,正確消息仍然送給monitor(不變)

exec 4>&1;(ls you no 2>&1 1>&4 4>&-;ls wu 2>&1 1>&4 4>&-)|egrep \* >file;
exec 4>&-
或者
exec 4>&1;(ls you no;ls wu) 2>&1 1>&4 4>&-|egrep \* >file;exec 4>&-

r2007
兄在其貼已有詳細說明,如果加兩個條件:
1)要求cmd1cmd2并行運行;
2)將cmd1的返回值賦給變量 ss。

則為:
exec 3>&1;exec 4>&1
ss=$(((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file) 4>&1)
exec 3>&-;exec 4>&-

說明:
exec 3>&1;4>&1
###
建立FD3,是用來將下面ls那條語句(子shell)中的FD1 恢復(fù)到正常FD1,即輸出
monitor,你可以把FD3看作最初始的FD1的硬盤備份(即輸出到monitor);
###
建立FD4,到時用作保存ls的返回值(echo $?),你可以將FD4看作你考試時用于
存放計算“echo $?”的草稿紙;

(ls you no 2>&1 1>&3 3>&-;echo $? >&4)
###
大家還記得前面說的子shell和管道吧。這條命令首先會繼承FD0FD1、FD2、FD3、FD4,它位于管道前,所
以在運行命令前會先把子shell自己的FD1和管道“|”相連。
但是我們的條件是stderr通過管道送往egrep,stdout仍然輸出到monitor。
于是通過2>&1,先把 shellFD1 的管道送給”FD2,于是子shell中的stderr送往
管道“|”;
再通過 1>&3,把以前的硬盤備份恢復(fù)給子shellFD1,于是子shell中的FD1變成
送到monitor了。
再通過3>&- ,將3關(guān)閉;
接著運行echo $? ,本來其輸出值應(yīng)該送往管道的,通過 >&4 ,將 輸出 送往草稿
”FD4,留以備用。

((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file)
于是,stderr 通過管道送給 egrep ,stdout 送給monitor,但是,還有 FD4,它送到
哪去了?
$(((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file) 4>&1)
最后的 4>&1 ,就是把FD4 重定向到 FD1。但由于其輸出在 $( )中,其值就賦給變量
ss
了。

最后一行關(guān)閉 FD3、FD4。


6
、高階例子
lightspeed
版主大大的:Shell 經(jīng)典問題之 [ I/O 重定向]
http://bbs.chinaunix.net/forum/view...show_type=new
[Q]
對于命令 cmd1, cmd2, cmd3, cmd4. 如何利用單向管道完成下列功能:
1.
所有命令并行執(zhí)行
2. cmd1
cmd2 不需要 stdin
3. cmd1
cmd2 stdout 定向到 cmd3 stdin
4. cmd1
cmd2 stderr 定向到 cmd4 stdin
5. cmd3
stdout 定向到文件 a, stderr 定向到屏幕
6. cmd4
stdout 定向到文件 b, stderr 定向到屏幕
7. cmd1
的返回碼賦給變量 s
8.
不能利用臨時文件

解決方法:
exec 3>&1; exec 4>&1
my_value=$(((((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 )
2>&1 | cmd4 >b ) 4>&1)
exec 3>&-; exec 4>&-

解釋:
exec 3>&1; exec 4>&1
建立FD3 ,給cmd1恢復(fù)其FD1用和給cmd3 恢復(fù)其FD2用;
建立FD4,保存“echo $?”輸出值的草稿紙

第一對括號到第一個管道:(cmd1 1>&3 ; echo $? >&4 )|
cmd1
本身沒有stdin,其stdout原要送往第一個管道,由于1>&3的作用,其stdout
送往FD3;而 >&4 的作用實際是將 cmd1 運行后的返回碼送往 FD4cmd1stderr默認
等待下一步處理。最后,沒有往管道送任何東西;

第二對括號到第二個管道:((cmd1 1>&3 ; echo $? >&4 )| cmd2) 3>&1|
由于第一個括號中cmd1 stdout 被送往 FD3,導(dǎo)致管道左端沒有任何輸入,cmd2
從而就沒有stdin。cmd2 stdout則為默認的;
將第二對括號看出一個命令,其所有的stdout送往第二個管道“|”;同時由于3>&1
的作用,原先cmd1stdout在送往FD3 又與cmd2stdout并到一起,所以cmd1 cmd2
stdout 都送往第二個管道“|”。而cmd1、cmd2stderr仍然默認等待下一步處理;

第三對括號到第三個管道:(((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 |
cmd3 >a 2>&3 ) 2>&1|
cmd3 >a 2>&3
cmd3接收處理來自管道的stdin后,其 stdout 送給文件a,其stderr
送往FD3,由于FD3繼承FD1,實際上其stderr是送往monitor。如果沒有“2>&3”,那么
cmd3
stderr就會干擾cmd1cmd2的錯誤輸出,所以它是必須的;
將第三個括號里完全看作一個命令,其stdout送往管道 “|”,由于2>&1,于是
stderr
也送往著管道。但由于cmd1、cmd2stdout已經(jīng)送給了cmd3處理,而cmd3
stdout
輸出到文件a,cmd3stderr也送往monitor,所以實際上只有cmd1cmd2
stderr
送往管道。

cmd4 >b
cmd4接收處理來自管道的stdin后,其stdout 定向到文件 b,
stderr
默認輸出到monitor

第四對括號:( (((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 | cmd3 >a
2>&3 ) 2>&1| cmd4 >b ) 4>&1
四對括號里面所有命令的 FD1、FD2都處理完了,但是還有“echo $? >&4”沒處理。
“4>&1”
的作用就是FD4并到stdout”,但由于其他命令的stdout都處理完了,實際
上就只有 $? 的值。
又由于 $() 會建立一個管道,輸入端為()內(nèi)命令,故 $? 的值被賦給變量my_value。

最后一行是關(guān)閉FD3FD4
另:恢復(fù)重定向或關(guān)閉的stdoutexec 1>&2 ,恢復(fù)重定向或關(guān)閉的stderrexec
2>&1
。如果stdoutstderr全部都關(guān)閉了,又沒有保存原來的FD,可以用:exec 1>
/dev/tty
恢復(fù)。

+++++++++++++++++++++++++++++++
我嘗試回答下面的問題。如有錯誤,還請各位前輩指正!


7
、在一個交互式的(Interactive) shell , exec 進行 I/O 重定向.
1
. Stdin, stderr 可以定向到文件中嗎? 有什么結(jié)果?
a
、在交互式shell中,可以將stdin定向到文件。執(zhí)行:exec 0<in
結(jié)果為:in 文件中每一行均會被自動執(zhí)行,并且在最后會再加執(zhí)行一個 exit 命令,
導(dǎo)致退出(或退回到正常shell下)。
in 文件內(nèi)容:$ more in
date
read lsp
echo hahha
echo "this is $lsp"

在提示符下執(zhí)行命令:$ exec 0<in (以下為自動輸出,除 # # 后那行的內(nèi)容)
$ date
Tue Jan 18 18:29:07 HKT 2005
$ read lsp #
其下面本應(yīng)有的那句“ echo hahha ” “hahaha”
已經(jīng)被讀入到變量 lsp 中了
$ echo "this is $lsp"
this is echo hahha
$ exit

b
、在交互式shell中,可以將stderr定向到文件。執(zhí)行:exec 2>err
結(jié)果為:命令提示符PS被屏蔽,輸入的命令也被屏蔽。但是命令執(zhí)行的結(jié)果,如果是
stdout
則會回顯到屏幕上,如果是 stderr 則不會回顯到屏幕上。其中,命令提示符、
命令、stderr均會保存到文件 err 中。如:
$ exec 2>err
err in out #
執(zhí)行 ls 命令
Tue Jan 18 18:55:58 HKT 2005 #
執(zhí)行 date 命令,而后執(zhí)行了“ ls
nofile”
,nofile這個文件不存在
$ #
執(zhí)行 exit 命令

現(xiàn)在讓我們查看 err文件:
$ more err
[lsp@ii lsp]$ ls
[lsp@ii lsp]$ date
[lsp@ii lsp]$ ls nofile
ls: nofile: No such file or directory
[lsp@ii lsp]$ exit
exit

c
、在交互式shell中,可以將stdout定向到文件。這個使我們常用到的。就不說了。
就是將錯誤的輸出內(nèi)容定向到文件中。正確的輸出內(nèi)容并不受影響。

2
. Stdin, Stderr 可以關(guān)閉嗎? 有什么結(jié)果?
在交互式shell中,如果關(guān)閉stdin,如:exec 0<&- ,其結(jié)果是退出(或退回到正常
shell
下)。
在交互式shell中,如果關(guān)閉stderr,如:exec 2>&- ,狀態(tài)同stderr定向到文件,唯一
不同的是沒有保存下來。
在交互式shell中,如果關(guān)閉stdoutr,如:exec 1>&- ,只要執(zhí)行有stdoutstderr內(nèi)容
送往 monitor 的命令,如ls、date這類命令,均會報錯:“ls: write error: Bad file
descriptor”
。其他如cdmkdir、……這類命令不受影響。

3
. 如果 stdin, stdout, stderr 進行了重定向或關(guān)閉, 但沒有保存原來的 FD,
以將其恢復(fù)到 default 狀態(tài)嗎?
***
如果關(guān)閉了stdin,因為會導(dǎo)致退出,那肯定不能恢復(fù)。
***
如果重定向或關(guān)閉 stdoutstderr其中之一,可以恢復(fù),因為他們默認均是送往
monitor
(但不知會否有其他影響)。如恢復(fù)重定向或關(guān)閉的stdoutexec 1>&2 ,恢復(fù)
重定向或關(guān)閉的stderrexec 2>&1。
***
如果stdoutstderr全部都關(guān)閉了,又沒有保存原來的FD,可以用:exec 1>
/dev/tty
恢復(fù)。



8
、cmd >a 2>a cmd >a 2>&1 為什么不同?
cmd >a 2>a
stdoutstderr都直接送往文件 a a文件會被打開兩遍,由此導(dǎo)致
stdout
stderr互相覆蓋。
cmd >a 2>&1
stdout直接送往文件a ,stderr是繼承了FD1的管道之后,再被送往
文件a 。a文件只被打開一遍,就是FD1將其打開。

他們的不同點在于:
cmd >a 2>a
相當于使用了FD1、FD2兩個互相競爭使用文件 a 的管道;
cmd >a 2>&1 只使用了一個管道FD1,但已經(jīng)包括了stdoutstderr。
IO效率上來講,cmd >a 2>&1的效率更高。

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux IO重定向
stdin, stdout, stderr以及重定向
Unix如何工作:您不敢問的一切
I/O重定向的原理和實現(xiàn)
玩轉(zhuǎn)Linux文件描述符和重定向
c語言輸出重定向【Z】
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服