Shell
管道如何影響標準輸入?
我想寫一個 C 程序,我需要解析
stdin
. 如果我輸入,從cat file.txt | grep -v match
如何解決?它們是串聯的嗎?它們是兩個不同的字元串嗎?我跑了,所以我沒有發現任何(似乎)有用的東西。stdout``cat``-v match``cat /dev/pts/0``file /dev/pts/0
C 程序主函式的標准定義是
int main(int argc, char *argv[])
在這裡,
argc
和argv
是命令行參數,-v
在這種情況下match
是 for 。grep
請注意,它們不是單個字元串,但 shell 已經將參數拆分為不同的字元串(NUL/\0
終止,就像 C 中的通常情況一樣)。argc
包含參數的數量和argv
參數本身。另一方面,標準輸入只是一個
FILE *
,您可以直接將它與任何stdio
功能一起使用。fgets(buf, sizeof(buf), stdin)
等等我不確定你從哪裡得到
cat /dev/pts/0
的。它將從那個特定的偽終端讀取,可能與您的 shell 在同一終端上的讀取衝突。(嘗試打開兩個終端,xterm,SSH 會話,螢幕,等等。然後tty
在第一個上執行,它在那裡顯示終端的名稱,例如/dev/pts/123
。在第二個終端中執行cat /dev/pts/123
(使用給定名稱),然後嘗試輸入第一件事。)
管道是在核心中分配的緩衝區,文件描述符與讀寫端相關聯。當你執行
cat file.txt | grep -v match
:
- shell 創建一個管道(使用
pipe()
系統呼叫)- 貝殼
fork()
s. 子程序使用dup2()
系統呼叫關閉其標準輸出流並將管道的寫入端複製到標準輸出。(此後,對標準輸出的寫入將轉到核心緩衝區。)然後子exec()
scat
具有更新的標準輸出。- 殼
fork()
再次。子程序使用dup2()
系統呼叫關閉其標準輸入流並將管道的讀取端複製到標準輸入。(在此之後,標準輸入的讀取將來自核心緩衝區。)然後子exec()
sgrep
具有更新的標準輸入。此時,兩者
cat
都grep
在執行。如果grep
嘗試從標準輸入(管道)讀取並且管道為空,則讀取將阻塞。如果cat
嘗試寫入標準輸出(同樣是管道)並且管道已滿,則寫入將阻塞。否則,當cat
寫入緩衝區時,grep
可以從緩衝區中讀取。