Coreutils

我不應該使用 stdbuf 的完全緩沖模式嗎?

  • December 11, 2018

在我的系統(最近更新的 Arch Linux)上,手冊頁stdbuf的“BUGS”部分有以下內容:

在 GLIBC 平台上,指定緩衝區大小,即使用完全緩沖模式將導致未定義的操作。

除了有點好奇為什麼會這樣以及“未定義的操作”是什麼意思之外,我最擔心的是這是否意味著我永遠不應該為命令指定緩衝區大小,以及它是否會在我面前爆炸我願意。

看起來這只是以前版本的遺留物stdbuf,不再符合現實。

在來自原始碼的評論stdbuf中,它說:

/* Note currently for glibc (2.3.5) the following call does not change
   the buffer size, and more problematically does not give any indication
   that the new size request was ignored:
       setvbuf (stdout, (char*)NULL, _IOFBF, 8192);

但是實際的程式碼繼續執行並且(不情願地?)分配緩衝區本身而不是依賴 C 庫來執行它,完全繞過了這個有問題的行為。

      if (size > 0)
        {
          if (!(buf = malloc (size))) /* will be freed by fclose()  */

此外(來自同一評論)似乎不再是這種情況:

   Another issue is that on glibc-2.7 the following doesn't buffer
   the first write if it's greater than 1 byte.
       setvbuf(stdout,buf,_IOFBF,127);

無論我對-iand-o選項給出什麼論據,它似乎都能很好地處理它們。例子:

$ echo 'int main(){ int c; while((c=getchar()) != EOF) putchar(c); }' | cc -include stdio.h -x c - -o slowcat
$ strace -s5 -e trace=read,write stdbuf -i143 -o127 2>&1 ./slowcat </dev/zero >/dev/null | awk '/ELF/{next}1;++n>5{exit}'
read(0, "\0\0\0\0\0"..., 143)           = 143
write(1, "\0\0\0\0\0"..., 127)          = 127
read(0, "\0\0\0\0\0"..., 143)           = 143
write(1, "\0\0\0\0\0"..., 127)          = 127
read(0, "\0\0\0\0\0"..., 143)           = 143
write(1, "\0\0\0\0\0"..., 127)          = 127

引用自:https://unix.stackexchange.com/questions/486960