A partir da solicitação inicial, eu entendo que você precisa mesclar 3 imagens (1 do arquivo e 2 geradas) em uma foto, considerando que você só pode trabalhar com 2 na ocasião.
Eu também entendo que você não quer dados temporários armazenados em disco. A solução mais rápida seria usar "tmpfs" como sugerido na resposta anterior por @ nominal-animal.
Mas dando um passo adiante, é possível evitar a criação de arquivos temporários e, basicamente, fazer todo o processamento em um único disparo. A solução que encontrei é usar "pipes nomeados", são arquivos especiais que não armazenam dados no disco e colocam até mesmo qualquer transferência nos canais até que a parte receptora também esteja pronta. Eu não usarei comandos completos como você forneceu (apenas o comando, entradas e saída), sinta-se livre para preencher os argumentos que você precisa.
# First it's necessary to have the pipes created, one time operation and they can be reused over and over.
mknod /tmp/pipe1 p
mknod /tmp/pipe2 p
mknod /tmp/pipe3 p
# generate the 2 images and send each to a pipe
gm convert ... miff:- > pipe1 &
gm convert ... miff:- > pipe2 &
# merge the source image to the 1st generated image
gm composite ... source.tif pipe1 miff:- > pipe3 &
# finally merge the result to the 2nd generated image
gm composite ... pipe3 pipe2 out.tif
Parece que a operação é feita em 4 etapas, mas, na verdade, tudo será feito de uma só vez sem que nada seja gravado no disco.
Veja como funciona e por que os comandos estão escritos como estão:
- o comando para gerar a 1ª imagem começará a trabalhar na solicitação, mas a saída deve ir para o canal nomeado. Porque neste momento nada está lendo do tubo a saída vai parar esperando por um recebido. O processo não vai sair ou exibir nenhum erro, então, para continuar, ele é colocado em segundo plano.
- segunda imagem mesma coisa apenas pipe diferente.
- a fusão da imagem de origem e os dados do primeiro canal farão com que ele leia de pipe1 e libere o primeiro comando de geração, mas como sua saída vai para outro canal, ele terá que esperar pela etapa final. A fusão dos dados do pipe3 e pipe2 finalizará a operação e gerará o arquivo de saída desejado e liberará os dois comandos anteriores.
Você pode considerar os canais como os arquivos temporários que não são arquivos, lembre-se de colocar algumas coisas em segundo plano, caso contrário, o script aguardará sua CTRL + C. Cada comando deve ser colocado em segundo plano separadamente! Não há nenhum problema se você colocá-los em um script como este, uma vez que a saída é gerada para os comandos anteriores.
Um recurso interessante é que você pode iniciar qualquer comando 3 primeiro em segundo plano e o último normalmente, já que todos os 4 dependem de dados de pipes. Também é fácil estender a vários comandos apenas adicionando mais pipes.
Há uma limitação que vejo, você não pode usar os mesmos canais em paralelo, se você precisar usar diferentes conjuntos de canais para cada instância em execução em paralelo, caso contrário, haverá surpresas :) O processamento sequencial não tem esse problema.
Do ponto de vista do desempenho, não sei se isso é mais rápido do que criar arquivos temporários em um "tmpfs", portanto, você precisará descobrir testando-o no cenário real. Para que isso funcione, você deve ter memória suficiente para acomodar todos os 4 processos com seus dados na memória. (depende muito do tamanho das imagens que você processa / gera).