「より大きい」構文でプログラム出力をリダイレクトしようとする場合(例:foo 2> myfile
)、ここで可能な数は何ですか、そしてそれらは何を表していますか?
1は/dev/stdout
、2は/dev/stderr
。 5と6はどうですか? 3、4、または6より大きい数はありますか?
この想定されるプログラムは、指定したファイル記述子番号に書き込みます。次の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)
数字はファイル記述子(開かれたファイルへのハンドル)を表します。
シェルには通常、自動的に3つのセットがあります。
0-stdin 1-stdout 2-stderr
ただし、さらにファイルを開くことができ、数が増えます。
それらの番号は ファイル記述子 です。お気づきのように、自動的に作成されるものがいくつかあります。他のファイルまたはファイルのようなものが開かれると、それらは他の番号を取得します。
特定のプログラムで使用される番号は、そのプログラムによって開かれたファイル、またはその他の方法で使用されたファイルによって異なります。たとえば、現在の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>
のすべての開いているファイル記述子と、それらが関連付けられているファイルを示しています。
すべてのプロセスはファイル記述子として整数を取得します。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
によって参照されるファイルのファイル記述子の番号です。