web-dev-qa-db-ja.com

プログラム出力リダイレクト

「より大きい」構文でプログラム出力をリダイレクトしようとする場合(例:foo 2> myfile)、ここで可能な数は何ですか、そしてそれらは何を表していますか?

1は/dev/stdout、2は/dev/stderr。 5と6はどうですか? 3、4、または6より大きい数はありますか?

11

この想定されるプログラムは、指定したファイル記述子番号に書き込みます。次のHelloWorldプログラムを検討してください。

#include <stdio.h>

main()
{
   ssize_t i = 0 ;
   printf ("hello world\n") ;
   i = write( 5 , "Bonjour Monde\n", 14 ) ;
   printf ("%d octet dans 5\n", (int) i) ;
}

それをコンパイルする

me@mybox:~/tmp7$ make hw
cc     hw.c   -o hw

今簡単な実行

me@mybox:~/tmp7$ ./hw
hello world
-1 octet dans 5

5のファイルがないため、バイトは書き込まれません。

次の試み:

me@mybox:~/tmp7$ ./hw 5> u
hello world
14 octet dans 5
me@mybox:~/tmp7$ cat u
Bonjour Monde

ファイルとファイル記述子(例:5>u)を指定しながら、なんとか出力を取得できます。

実際には、上記のような面白いプログラムを作成していない限り、5>fooを使用してデータを収集することはほとんどありません。

シェルスクリプトでは、<()を使用した構成の方が便利です。

 diff <( cmd -par 1 ) <(cmd -par 2)
11
Archemar

数字はファイル記述子(開かれたファイルへのハンドル)を表します。

シェルには通常、自動的に3つのセットがあります。

0-stdin 1-stdout 2-stderr

ただし、さらにファイルを開くことができ、数が増えます。

10
X Tian

それらの番号は ファイル記述子 です。お気づきのように、自動的に作成されるものがいくつかあります。他のファイルまたはファイルのようなものが開かれると、それらは他の番号を取得します。

特定のプログラムで使用される番号は、そのプログラムによって開かれたファイル、またはその他の方法で使用されたファイルによって異なります。たとえば、現在のstdinを「保存」し、stdinを別の場所から一時的にリダイレクトして、後で復元する場合は、次のようにします。

exec 4<&0
exec < /some/file
#process
exec 0<&4 4<&- # restore stdin and close our duplicate

したがって、このスクリプトでは、少なくともしばらくの間、4ファイル記述子を使用できます。ただし、その4は、使用されていないものであれば何でもかまいません(プロセスで開くことができるファイルの数には制限がありますが、その制限内であれば何でもかまいません)。

/proc/<pid>/fdを調べると、プロセスが開いているファイル記述子と、それらが開いている場所を確認できます。これは、そのプロセス<pid>のすべての開いているファイル記述子と、それらが関連付けられているファイルを示しています。

7
Eric Renouf

すべてのプロセスはファイル記述子として整数を取得します。POSIXには3つの予約済みのものがあります。0はstdin、1はstdout、2はstderrです。それ以降のファイルには、さらに番号が割り当てられます。このプログラムで簡単に確認でき、fdtest.cとして保存して、実行時に独自のプログラムコードを開くようにします。

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd = open("fdtest.c", O_RDONLY);
    printf("%d\n", fd);
    close(fd);
    return 0;
}

それをコンパイルします:

gcc fdtest.c -o fdtest

それを実行します:

./fdtest

取得する出力は次のようなものです。

3

...これは、変数fdによって参照されるファイルのファイル記述子の番号です。

0
rexkogitans