の陳述を覆した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
なぜ//1
?cannot seek
私の考えでは、ソラはstdin
それを得ることができると思います。stdin
まだオープンしていないのでしょうか?通常そのような言葉をstdin
聞き、プログラムが起動し始めると開きますstdout
。stderr
なぜ//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
。他のプロセスへの一方向接続があります。そしてこれらは見つかりません。