Respostas:
Eles trabalham de maneiras completamente diferentes.
O programa que o buffer de buffer usa espera executar o comando nomeado. Como o expect cria um pseudo-tty para anexar ao stdout do processo filho, o filho pode ser enganado ao pensar que deve usar buffer de linha em vez de buffer de bloco. Alguns programas mudam seu comportamento quando isatty (stdout) é verdadeiro, outros não e é muito difícil saber qual e o que não.
O programa stdbuf tenta colocar o libstdbuf na frente do libc para binários carregados dinamicamente. Onde libstdbuf redefine a estratégia de buffer padrão das chamadas libc stdio.
Eu descobri isso por
apt-get source expect coreutils
e lendo a fonte relevante para cada programa.
unbuffer -p
podem parecer funcionar incorretamente se houver um processo que alimenta a entrada do buffer. Considere:process1 | unbuffer -p process2 | process3
Se o processo1 sair, o processo2 poderá ainda não ter sido concluído. É impossível para unbuffer saber de esperar muito