天天看點

shell重定向小記

對于int型的,使用open,write,read,close操作,對于FILE*型的使用fopen,fwrite,fread,fclose操作

标準輸入,int fd = 0,int fd = STDIN_FILENO,FILE *f = stdin,shell重定向标準輸入使用"<",比如./hello <words.txt,那麼hello可以從fd=0或者f=stdin裡面讀取words.txt檔案中的内容,平時都是./hello words.txt這樣,可以從argv[1]中讀取檔案名,然後再open/read/close。

有種特殊的情況是這樣的,不一定需要使用EOF,任意單詞都可以,首尾相同:

有些程式可以接收參數"-",表示從标準輸入中讀取檔案内容

标準輸出,int fd = 1,int fd = STDOUT_FILENO,FILE *f = stdout,shell重定向标準輸出使用">"(覆寫方式),或者">>"(append方式),">"和">>"前面的預設數字是"1",比如:

錯誤輸出,int fd = 2,int fd = STDERR_FILENO,FILE *f = stderr,shell重定向錯誤輸出使用"2>"(覆寫方式),或者"2>>"(append方式),和标準輸出類似,注意使用">"對錯誤輸出無效:

并不一定是2這個數字,而是指錯誤輸出,例如:

有時候常用到"2>&1"這種,是将錯誤輸出重定向到标準輸出,為什麼要加"&"呢,因為不加就會重定向到一個名為"1"的檔案

如果标準輸出和錯誤輸出都需要重定向,那麼應該先寫标準輸出的,再寫錯誤輸出的:

/dev/null就是個垃圾桶,扔進去的都沒了,類似還有/dev/zero,從裡面可以讀出來無數的0

shell 使用"|"将上一條指令的标準輸出,作為下一條指令的标準輸入,例如:

可以使用proc看到每個程序打開了多少fd,以及fd打開的是誰(self可以替換為具體的pid):

每一個終端都對應/dev/pts下面的一個檔案,向對應的檔案寫入資料,那麼将會顯示在我們的終端上面,也可以和别的使用者打招呼,如果你sudo的話:

還有個比較有意思的就是pipe檔案,注意ls -l顯示出的檔案類型為"p":

可以一個程序将輸出寫到mypipe,另一個程序從mypipe檔案讀取第一個程序輸出的内容,

甚至可以這樣玩,先在一個終端上啟動nc伺服器:

另一個終端使用pipe檔案,将bash的标準輸出給nc的标準輸入,nc的标準輸出給bash的标準輸入:

這樣的話,就可以在第一個終端,輸入shell指令了,控制了第二個終端所在的機器

關于time,你沒法重定向time的輸出:

因為time是shell builtin的指令,重定向是由shell自己來處理的,使用time指令的時候,重定向的東西被當做普通參數了。是以time得到的argv={"ls", ">/dev/null", "2>&1"},而不是{"ls"}

如果是普通的程式,比如/usr/bin/time,重定向的東西就是重定向,沒法被當做普通參數,是以/usr/bin/time可以被重定向掉: