Eu fiz algumas investigações usando strace
e parece ser devido ao modo como o programa no lado esquerdo do pipeline faz a gravação no terminal. Quando o comando ls
é executado, ele grava todos os dados em um único write()
. Isso faz com que head
consuma todo stdin.
Por outro lado, ps
grava dados em lotes, portanto, apenas o primeiro write()
é consumido por head
e, em seguida, existe. Chamadas posteriores para write()
irão para o processo grep
recém-gerado.
Isso significa que não funcionaria se o processo para o qual você está tentando grep
não tivesse ocorrido no primeiro write()
, pois grep
não consegue ver todos os dados (ele vê até menos que apenas os dados menos a primeira linha).
Aqui está um exemplo de como tentar usar o pid 1 no meu sistema:
$ ps -eF | { head -n2; }
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 1 0 0 1697 3768 2 Oct03 ? 00:00:03 /lib/systemd/systemd
$ ps -eF | grep '/lib/systemd/systemd$'
root 1 0 0 1697 3768 2 Oct03 ? 00:00:03 /lib/systemd/systemd
$ ps -eF | { head -n1; grep '/lib/systemd/systemd$'; }
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
Seu exemplo ps -eF
só funciona por acaso.