presmerovani std a err do tehoz souboru: synchronizace, buffering?

Alexandr Malusek malusek na sysel.ujf.cas.cz
Pátek Srpen 22 18:46:22 CEST 1997


"Róbert Drotár" <drotar na ipg.sk> writes:

>  Mne sa osvedcilo
> ./program 2>&1 | more > subor

To by nemelo fungovat. Spis bych rekl, ze pokud Vam to funguje, pak
mate spatne zkompilovanou knihovnu libc ;-)

Jan Kasprzak problem velmi dobre popsal - problem je nutne resit na
urovni knihovny libc, nikoliv na urovni jadra. Nepomuze tedy ani
presmerovani pres rouru, ani synchronni zapisy, ... je potreba omezit
bafrovani streamu stdout definovaneho v libc pomoci setvbuf, ...
protoze bafrovani po radcich se dela pouze v pripade vystupu na
terminal, jinak se dela bafrovani po blocich (viz libio/filedoalloc.c
v glibc). stderr neni bafrovany vubec.

Celkem hezky je to videt
v nasledujicich prikladech:

$ ./c2            # Na terminal je bafrovani po radcich
stdout: 0
stderr: 0
stdout: 1
stderr: 1

$ ./c2 > o 2>&1   # Do souboru je bafrovani po 4 KB blocich.
$ cat o           # BUFSIZ v stdio.h ma hodnotu 1024, ale
stderr: 0         # bere se hodnota st_blksize (viz man 2 stat)
stderr: 1
stdout: 0
stdout: 1

strace vypisuje v prvnim pripade:
...
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(3, 4), ...}) = 0
...             # ^^^^^^^ character device (viz man 2 stat) 
write(1, "stdout: 0\n", 10stdout: 0) = 10  # OS dostava od aplikace
write(2, "stderr: 0\n", 10stderr: 0) = 10  # zapisy ve spravnem poradi,
write(1, "stdout: 1\n", 10stdout: 1) = 10  # protoze bafrovani stdout
write(2, "stderr: 1\n", 10stderr: 1) = 10  # je po radcich

ve druhem pripade:
...
fstat(1, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
...             # ^^^^^^^ regular file
write(2, "stderr: 0\n", 10) = 10    # stderr vystup jako v predchozim
write(2, "stderr: 1\n", 10) = 10    # pripade nebafruje, zatimco     
write(1, "stdout: 0\nstdout: 1\n", 20) = 20  # stdout ano

Soubor c2.c:
#include <stdio.h>
#define IMAX 2
int main()
{
  int i;

  for (i = 0; i < IMAX; i++) {
      fprintf(stdout,"stdout: %d\n", i);
      fprintf(stderr,"stderr: %d\n", i);
  }
  return 0;
}

-- 
Alexandr Malusek (malusek na ujf.cas.cz)
UJF AV CR


Další informace o konferenci Linux