Execute o comando no shell atual antes de cada prompt

4

Gostaria de ter o status jobs atual exibido no título do meu terminal. No Bash, eu posso usar PROMPT_COMMAND para isso. Korn Shell (ksh93) não tem isso.

Outras respostas sugiro usar a substituição de comandos dentro de $PS1 , que funciona bem no caso geral, mas não para o comando jobs . O problema aqui é que jobs está preocupado com as tarefas do shell atual , mas a substituição de comandos (ie PS1='...$(jobs)...' ) é executada em um subshell , portanto existem sem emprego.

O único mecanismo do qual estou ciente é trap '... jobs ...' DEBUG , mas isso seria executado com muita frequência. Você conhece uma maneira de executar comandos no contexto do shell atual, uma vez em cada prompt, ou isso não é possível no shell Korn?!

    
por Ingo Karkat 08.07.2016 / 13:39

2 respostas

3

Por padrão, se você apenas definir PS1="...." , o material dentro das aspas é avaliado no momento em que você o define.

No entanto, se você colocá-lo dentro de ' , ele será avaliado no momento da exibição. E isso não causa um subshell para $(jobs) .

por exemplo,

$ PS1='
> $(jobs)
> $ '


$ sleep 1000 &
[1] 7541

[1] +  Running                 sleep 1000 &
$ sleep 1000 &
[2] 7543

[2] +  Running                 sleep 1000 &
[1] -  Running                 sleep 1000 &
$ kill %1
[1] - Terminated               sleep 1000 &

[2] +  Running                 sleep 1000 &
$ kill %2
[2] + Terminated               sleep 1000 &


$ 

(Este teste feito no Debian Jessie com o ksh93, mas deve funcionar em todas as variantes do ksh93; eu não tenho nenhum ksh88 para testar.)

    
por 08.07.2016 / 13:52
1

Meu problema real foi que (em contraste com o exemplo simplificado da minha pergunta), eu realmente massageei a saída jobs em uma função, separando a execução de trabalhos interrompidos.

Este é o meu código para o Bash:

typeset runningJobs=$(jobs -r | wc -l)
typeset stoppedJobs=$(jobs -s | wc -l)

que eu portei para o shell Korn desta forma:

typeset runningJobs=$(jobs | grep -c ' Running ')
typeset stoppedJobs=$(jobs | grep -c ' Stopped ')

O pipeline dentro da substituição do comando $(...) estava realmente causando jobs a ser executado em uma subshell (e, portanto, sempre não produzia saída). Ao capturar a saída em uma variável, isso pode ser evitado. A reescrita a seguir funciona conforme o esperado:

typeset jobOutput=$(jobs)
typeset runningJobs=$(printf '%s\n' "$jobOutput" | grep -c ' Running ')
typeset stoppedJobs=$(printf '%s\n' "$jobOutput" | grep -c ' Stopped ')

Agradecemos a @StephenHarris pela sua resposta, que me ajudou a entender o problema real!

    
por 08.07.2016 / 17:24

Tags