
這是一個檢查標準輸入來源的腳本,
摘自 How-to Geek:“Linux 上的 stdin、stdout 和 stderr 是什麼?”
https://www.howtogeek.com/435903/what-are-stdin-stdout-and-stderr-on-linux/
#!/bin/bash
if [ -t 0 ]; then
echo stdin coming from keyboard
else
echo stdin coming from a pipe or a file
fi
那麼如果任何命令使用參數或命令替換執行,它與 沒有關係嗎stdin
?在這種情況下,是stdin
空的嗎?
雖然我可以理解來自管道或文件的含義,但是來自鍵盤的stdin
含義是什麼?stdin
它是類似於read
命令或此處文檔的按鍵輸入嗎?
感謝社區每天的支持。
答案1
command line arguments
為了揭開和之間的區別stdin
。我將把我的答案分成多個部分來解釋基本概念。然後回答你的問題。
在我開始解釋之前,請記住以下幾點:
- 在 Linux 中,一切都被視為檔案。
- 我假設您已經閱讀了問題中提供的整篇文章。
- 我將藉助 C 程式來解釋其中的差異,因此我假設您了解基本語法。不過我會盡可能地解釋。
標準輸入和命令列參數
標準輸入是 Linux 中的一個文件,程式可以存取該文件以取得使用者的輸入。任何程式都不能直接與鍵盤交互,而是與stdin
.因此,如果程式需要從用戶那裡獲取輸入,它將訪問stdin
.
當您使用重定向 ( > or <
) 或管道 ( |
) 與其他命令時,它會操縱輸入和輸出流,即stdin
和stdout
。當您指定這些特殊字元時,它們會指示stdin
以及stdout
如何運作。在 Linux 中,stdin
是/proc/self/fd/0
和stdout
是/proc/self/fd/1
命令列參數基本上是一種從使用中獲取輸入以及調用命令以使命令執行某些特定任務的方法。沒有必要每個程式都有命令列參數,因為由以下程式的開發人員來使用它們。
命令列參數作為數組傳遞給命令。 (數組是一種由元素集合組成的資料結構,每個元素由至少一個數組索引或鍵標識。)。因此,程式設計師可以使用該數組中的值向其程式添加更多功能。
C 程式範例
#include<stdio.h>
int main(int argc, char *argv[]) {
if(argc==2)
printf("Welcome Master %s\n", argv[1]);
else {
fprintf(stderr, "Usage : %s <name>\n", argv[0]);
return 1;
}
return 0;
}
在上面的程式中,程式不接受使用者的任何標準輸入,但它接受命令列參數,並且根據是否提供參數而工作不同。
argc
是一個變量,用於儲存傳遞的參數的計數,並且argv
是一個數組,用於儲存呼叫程式時傳遞的參數。argv[0]
是數組中包含程式本身名稱的第一個元素。之後該數組將包含傳遞的參數。
當我輸入“./batman”執行以下程序時,我得到以下輸出:
用法:./蝙蝠俠
但是當我透過輸入“./batman Bruce”來執行相同的程序。我得到:
歡迎布魯斯大師
現在這並不意味著該程式無法接受輸入。下面是修改後的程序,它同時採用命令列參數和標準輸入。
#include<stdio.h>
int main(int argc, char *argv[]) {
int pass = 0;
if(argc==2){
printf("Welcome Master %s\n", argv[1]);
printf("Kindly provide password : ");
scanf("%d", &pass);
if(pass==1234)
printf("Batcave Access granted\n");
else
printf("Batcave Access declined\n");
}
else {
fprintf(stderr, "Usage : %s <name>\n", argv[0]);
return 1;
}
return 0;
}
上面的程式碼採用命令列參數,然後等待使用者透過標準輸入輸入密碼。
如果我們不指定任何參數,它將拋出一個錯誤,就像之前的 C 程式碼一樣。
以下是程式執行時的輸出:
mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman3 Bruce Welcome Master Bruce Kindly provide password : 1234 Batcave Access granted mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman3 Joker Welcome Master Joker Kindly provide password : 123 Batcave Access declined mars@HP-Notebook:~/Desktop/Practice/cpp$
傳遞命令列參數後,程式等待使用者輸入的密碼,因此透過stdin
那麼結論是什麼呢?
我希望您理解我上面解釋的概念。現在是時候回答這些問題了。- 是的,命令列參數與您的輸入設備沒有關係
stdin
,stdin
在這種情況下只是指向您的輸入設備但沒有被使用。 stdin
is 本身是一個文件,預設指向您的輸入裝置並從那裡獲取輸入。但是,當您在命令中提供管道或重定向時,它會告訴stdin
從您指定的檔案中取得輸入,而不是從連接到電腦的輸入裝置中取得輸入。
如果你不懂 C 程式也沒關係。這次讓我們使用內建命令而不是定製程式。
命令而不是程式的範例:
cat file_name
cat < file_name
輸出將是相同的,因為相應的開發人員cat
要么從stdin
文件中讀取數據,要么從文件中讀取數據,其名稱作為第一個命令行參數給出(這是shell 傳遞給cat 的數組中的第一個元素)。
隨後 cat 將 file_name 或 的全部內容寫入stdin
終端,因為我們不指示 shell 操作stdout
.請記住,在第二行中,您的 shellstdin
以這種方式進行操作,它不再指向您的標準輸入設備,而是指向當前工作目錄中名為 file_name 的檔案。這個範例取自另一篇文章,你可以點擊這裡閱讀更多
我希望這不僅能為您提供問題的解決方案,還能幫助您理解基本概念。