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.