Você está fazendo errado. at lê os comandos do stdin como texto, não pode magicamente conhecê-los de um pipeline.
Seu comando ...
echo 'foo' >> path/to/log.txt | at now + 2 minutes
... executa ambos echo e at ao mesmo tempo, em um pipeline. (Pense em cat somefile | grep sometext ) Então at receberia a palavra foo em sua stdin. No entanto, a saída de echo é redirecionada para um arquivo, portanto, at não recebe nada.
O comando correto seria:
echo "echo 'foo' >> path/to/log.txt" | at now + 2 minutes