Exibindo stdout de um processo em segundo plano no local específico do terminal

8

Eu tenho um comando que executo toda vez que um novo terminal é aberto ou um novo login é feito.

Este programa produz saída (colorida) que deve ser posicionada antes do prompt de comando. Pode demorar alguns segundos para ser executado, o que me impedirá de usar o terminal até então (a menos que seja executado em segundo plano).

Dado que o zsh tem algumas formas avançadas de redesenhar o terminal sem danificar o texto existente, eu gostaria de saber como posso executar este comando de uma forma que eu não tenha que esperar que ele termine antes que eu possa usar o comando. terminal, mas que, uma vez terminado, imprime a saída como se não estivesse em segundo plano.

Na prática, gostaria de algo que pudesse fazer:

Command output:
... (running on background)
me@computer: somecommand
me@computer: someothercommand

e assim que o comando terminar, eu recebo:

Command output:
 * Output foo
 * Multiple lines bar
 * and some yada
me@computer: somecommand
me@computer: someothercommand

Eu tentei colocar o processo em segundo plano no início, mas ele não exibe a saída de forma limpa. Eu recebo algo como:

Command output:
[2] 32207
me@computer: somecommand
me@computer: someother * Output foo
 * Multiple lines bar
 * and some yada
[2]  + done       command
me@computer: someothercommand

Então, isso é possível? Se não com zsh, existe alguma solução que poderia fazer isso?

Todos os ponteiros ou informações são bem-vindos.

    
por unode 27.05.2011 / 13:05

1 resposta

4

Esta é uma solução simples se você estiver disposto a aceitar a saída logo acima da linha de prompt atual.

TRAPUSR1 () { zle -I; unfunction TRAPUSR1 }  # invalidate prompt on signal USR1

bufferout () {
    local buffer
    while read -r line; do                   # buffer lines from stdin
        buffer="$buffer$line\n"
    done
    print -rn -- $terminfo[dl1]              # delete current line
    print -rn -- $terminfo[cr]               # move cursor to BOL
    printf "$buffer"                         # print buffer
    kill -USR1 $$                            # send USR1 when we're done
}

unsetopt monitor                             # don't monitor this job
./testout |& bufferout & disown              # bg and disown to suppress notification
setopt monitor                               # restore job monitoring

Quando o trabalho estiver concluído, o prompt atual e o buffer de entrada serão removidos e a totalidade dos stdout e stderr do comando será impressa.

Você pode obter muito mais fantasia do que isso com o módulo zsh/curses , mas duvido que ofereça uma vantagem significativa o suficiente para merecer o esforço.

    
por 24.02.2012 / 19:52

Tags