stdin とコマンドライン引数

stdin とコマンドライン引数

以下は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基礎となる概念を説明しながら、回答を複数の部分に分けて説明します。その後で、ご質問にお答えします。

説明を始める前に、次の点に留意してください。

  1. Linux ではすべてがファイルとして扱われます。
  2. 質問で提供されている投稿全体を読んだものと想定します。
  3. 違いを説明するために C プログラムを使用しますので、基本的な構文はご存知であると想定しています。それでも、できる限り説明します。

stdin とコマンドライン引数

標準入力は、ユーザーからの入力を取得するためにプログラムがアクセスする Linux ファイルです。どのプログラムもキーボードと直接対話することはできず、代わりに と対話します。stdinしたがって、プログラムがユーザーからの入力を取得する必要がある場合は にアクセスしますstdin

> or <リダイレクト( )またはパイプ( )を他のコマンドで使用すると、|入力ストリームと出力ストリーム( と )が操作されます。これらの特殊文字を指定すると、 と がstdinどのように機能するかstdoutが指示されます。Linuxでは、は、 はです。stdinstdoutstdin/proc/self/fd/0stdout/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

それで結論は何でしょうか?

上記で説明した概念を理解していただけたと思います。次は、それらの質問に答えていきましょう。

  1. はい、コマンドライン引数は とは関係がなくstdinstdinその場合は入力デバイスを指しているだけで使用されていません。
  2. stdin自体は、デフォルトで入力デバイスを指し、そこから入力を取得するファイルです。ただし、コマンドでパイプまたはリダイレクトを指定すると、stdinコンピューターに接続されている入力デバイスではなく、指定したファイルから入力を取得するように指示されます。

C プログラムがわからなくても大丈夫です。今回は、カスタム プログラムではなく、組み込みコマンドを使用します。

プログラムの代わりにコマンドの例:

cat file_name
cat < file_name

対応する開発者が、最初のコマンドライン引数として名前が指定されたファイル (シェルが cat に渡す配列の最初の要素)catからデータを読み取るかstdin、ファイルからデータを読み取るかのいずれかを行うため、出力は同一になります。

その後、シェルに操作を指示していないため、cat は file_name または の全内容をstdin端末に書き込みますstdout。2 行目では、シェルがstdinこのように操作し、標準入力デバイスではなく、現在の作業ディレクトリにある file_name というファイルを指すようになることに注意してください。この例は別の投稿から引用したものです。続きを読むにはここをクリックしてください。

これで質問の解決策が得られただけでなく、基礎となる概念を理解するのにも役立ったと思います。

関連情報