
以下はstdinのソースを確認するスクリプトです。
これは 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 プログラムを使用しますので、基本的な構文はご存知であると想定しています。それでも、できる限り説明します。
stdin とコマンドライン引数
標準入力は、ユーザーからの入力を取得するためにプログラムがアクセスする Linux ファイルです。どのプログラムもキーボードと直接対話することはできず、代わりに と対話します。stdin
したがって、プログラムがユーザーからの入力を取得する必要がある場合は にアクセスしますstdin
。
> or <
リダイレクト( )またはパイプ( )を他のコマンドで使用すると、|
入力ストリームと出力ストリーム( と )が操作されます。これらの特殊文字を指定すると、 と がstdin
どのように機能するかstdout
が指示されます。Linuxでは、は、 はです。stdin
stdout
stdin
/proc/self/fd/0
stdout
/proc/self/fd/1
コマンドライン引数は、基本的に、コマンドの呼び出しと一緒に入力を受け取り、コマンドに特定のタスクを実行させる方法です。すべてのプログラムにコマンドライン引数が必要なわけではないこれらを使用するかどうかは、次のプログラムの開発者次第です。
コマンドライン引数は配列としてコマンドに渡されます。(配列は、各要素が少なくとも 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
しかし、「./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
自体は、デフォルトで入力デバイスを指し、そこから入力を取得するファイルです。ただし、コマンドでパイプまたはリダイレクトを指定すると、stdin
コンピューターに接続されている入力デバイスではなく、指定したファイルから入力を取得するように指示されます。
C プログラムがわからなくても大丈夫です。今回は、カスタム プログラムではなく、組み込みコマンドを使用します。
プログラムの代わりにコマンドの例:
cat file_name
cat < file_name
対応する開発者が、最初のコマンドライン引数として名前が指定されたファイル (シェルが cat に渡す配列の最初の要素)cat
からデータを読み取るかstdin
、ファイルからデータを読み取るかのいずれかを行うため、出力は同一になります。
その後、シェルに操作を指示していないため、cat は file_name または の全内容をstdin
端末に書き込みますstdout
。2 行目では、シェルがstdin
このように操作し、標準入力デバイスではなく、現在の作業ディレクトリにある file_name というファイルを指すようになることに注意してください。この例は別の投稿から引用したものです。続きを読むにはここをクリックしてください。
これで質問の解決策が得られただけでなく、基礎となる概念を理解するのにも役立ったと思います。