Pengalihan output program

11

Ketika mencoba mengarahkan output program dengan sintaks "beberapa angka lebih besar dari" (mis. foo 2> myfile), Berapa angka yang mungkin di sini dan apa yang mereka wakili?

Saya percaya 1 adalah /dev/stdout, 2 adalah /dev/stderr. Bagaimana dengan 5 & 6? Apakah ada angka 3, 4 atau lebih dari 6?

Mahasiswa Fermat
sumber
Lihat juga Kapan Anda akan menggunakan deskriptor file tambahan?
Gilles 'SO- stop being evil'

Jawaban:

11

Seharusnya program ini akan menulis ke file nomor deskriptor yang Anda tentukan. pertimbangkan program hello world berikut:

#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) ;
}

kompilasi itu

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

sekarang jalankan sederhana

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

tidak ada file untuk 5, jadi tidak ada byte yang menulis.

percobaan berikutnya:

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

Saya berhasil mendapatkan output saat menentukan file dan deskriptor file (misalnya 5>u).

Dalam praktiknya, kecuali jika Anda telah menulis program lucu seperti di atas, Anda tidak akan mengumpulkan data menggunakan 5>foo.

dalam skrip shell, konstruk menggunakan <() lebih bermanfaat:

 diff <( cmd -par 1 ) <(cmd -par 2)
Archemar
sumber
write()kembali ssize_t, tidak int.
Andrew Henle
Itu bukan poin utama dari pertanyaan, ada juga pengembalian untuk fungsi printf.
Archemar
Tidak menggunakan nilai yang dikembalikan jauh berbeda dengan menggunakan tipe yang salah .
Andrew Henle
diedit Saya tidak melihat perubahan output ...
Archemar
10

Angka-angka tersebut merupakan deskriptor file (pegangan ke file yang telah dibuka).

Shell biasanya memiliki 3 set secara otomatis,

0 - stdin 1 - stdout 2 - stderr

Tetapi file lebih lanjut dapat dibuka, dan jumlahnya bertambah.

X Tian
sumber
7

Angka-angka itu adalah deskriptor file . Seperti yang Anda catat, ada beberapa yang dibuat secara otomatis. Ketika file lain atau hal-hal seperti file dibuka, mereka akan mendapatkan nomor lain.

Angka-angka yang digunakan dalam program tertentu tergantung pada file apa yang telah dibuka oleh program itu, atau digunakan. Misalnya, jika Anda ingin "menyimpan" stdin saat ini dan sementara mengalihkan stdin dari tempat lain kemudian mengembalikannya nanti, Anda bisa melakukan sesuatu seperti:

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

Jadi skrip ini akan memiliki 4deskriptor file yang tersedia setidaknya untuk beberapa waktu. Angka 4 itu bisa berupa apa saja yang tidak digunakan (well, ada batas untuk berapa banyak file yang bisa dibuka oleh suatu proses, tetapi apa pun dalam batas itu).

Anda dapat melihat file deskriptor apa yang telah dibuka oleh suatu proses, dan di mana mereka terbuka dengan melihatnya /proc/<pid>/fd. Itu menunjukkan semua deskriptor file terbuka untuk proses itu <pid>dan file apa yang terkait dengannya.

Eric Renouf
sumber
0

Setiap proses mendapatkan angka integer sebagai deskriptor file, di mana ada tiga yang dicadangkan di POSIX: 0 adalah stdin, 1 adalah stdout dan 2 adalah stderr. File lebih lanjut akan diberi nomor lebih lanjut. Anda dapat memeriksa dengan mudah dengan program ini, simpan sebagai fdtest.c , sehingga membuka kode program sendiri selama runtime:

#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;
}

Kompilasi:

gcc fdtest.c -o fdtest

Menjalankannya:

./fdtest

Output yang akan Anda dapatkan adalah sesuatu seperti ini:

3

... yang merupakan jumlah deskriptor file dari file yang dirujuk oleh variabel fd.

rexkogitans
sumber