標準入力が見つかるかどうかをテストする際の問題

標準入力が見つかるかどうかをテストする際の問題

の陳述を覆したif/elseが、今訂正します。


次のコードスニペットを読んでいます。UNIX®環境の高度なプログラミング:

プログラムは標準入力をテストして照会を実行できることを確認します。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void){

    if(lseek(STDIN_FILENO,0, SEEK_CUR) == -1)
        printf("cannot seek\n");
    else{
        printf("seek ok\n");
    }
}

(以下で)コンパイルして実行しましたが、Ubuntu 18.04.2 LTS次の動作を理解していません。

//1
$ ./a.out 
cannot seek

//2
$ ./a.out < /etc/passwd
seek OK

//3
$ cat < /etc/passwd | ./a.out
cannot seek

//4
$ ./a.out < /var/spool/cron/FIFO
cannot seek

なぜ//1cannot seek私の考えでは、ソラはstdinそれを得ることができると思います。stdinまだオープンしていないのでしょうか?通常そのような言葉をstdin聞き、プログラムが起動し始めると開きますstdoutstderr

なぜ//2可能で、なぜ//3不可能ですか?私は彼らが同じだと思います。

答え1

//1 ./a.out:

stdinをリダイレクトしないと(パイプなしとno <)、stdinは親プロセスから継承されます。シェルで対話的に実行すると、a.outキーボード入力をstdinにインポートするターミナルデバイスを継承します。

ターミナルデバイスは通常、ユーザーの対話を示すため検索できませんが、POSIX規格によればlseek成功を返し、何もしないことがあります。 Linuxではlseekディスプレイが失敗しますESPIPE

//2 ./a.out < /etc/passwd:

ここで、stdin は開いたファイルにリダイレクトされます。/etc/passwd通常のファイルと同様に検索が可能です。

//3 cat < /etc/passwd | ./a.out:

catここでは、2つのプロセス(および)を起動し、./a.outそれをパイプに接続します。

cat(他の引数なしで)stdin(/etc/passwd)を読み取り、それをstdout(接続されたパイプ./a.out)にコピーします。これは状況とは異なります//2。標準入力の観点から見ると、./a.outナビゲーションは他のプロセスに接続されたパイプにすぎず、ナビゲーションを実行する方法はありません。

//4 ./a.out < /var/spool/cron/FIFO:

ここでは名前付きパイプまたは同様の特殊ファイル。この場合も同様です//3。他のプロセスへの一方向接続があります。そしてこれらは見つかりません。

関連情報