bash: como salvar o estado na avaliação imediata [duplicado]

2

Eu quero colocar a duração do último comando em execução no prompt de comando, f.ex:

user@host$ sleep 360
6m user@host$ 

Além disso, quero que a duração não apareça se for menor que um limite mínimo (digamos, 30 segundos).

Para conseguir isso, eu poderia colocar a chamada de função no PS1:

print_duration()
{
    ... calculation and formatting code ...
    echo -n $command_duration
}

PS1='$(print_duration)\u@\h:\W\$ '

O problema é: print_duration () será avaliado dentro do subprocesso, o que impedirá a mudança das variáveis de ambiente do main interactive bash.

Embora não tenha percebido o código acima, darei um exemplo mais simples, corte & cole isto no prompt de comando:

prompt_var=0

test_prompt()
{
    (( prompt_var++ ))
    echo -n "I was evaluated at $(date) and look at this: ${prompt_var} "
}

PS1='$(test_prompt)\$ '

E aqui está o resultado:

I was evaluated at Fri, Mar 27, 2015 16:27:48 and look at this: 1 $
I was evaluated at Fri, Mar 27, 2015 16:27:52 and look at this: 1 $
I was evaluated at Fri, Mar 27, 2015 16:27:53 and look at this: 1 $

Observe que, na verdade, test_prompt () foi avaliado no contexto do processo principal apenas uma primeira vez (suponho que verifique a validade da função). Mas, para a exibição imediata, ele faz isso no subprocesso (o que não é realmente interessante).

Embora se eu definir PROMPT_COMMAND como foi sugerido no comentário:

I was evaluated at Fri, Mar 27, 2015 16:38:02 and look at this: 1 $ PROMPT_COMMAND='(( prompt_var++ ))'
I was evaluated at Fri, Mar 27, 2015 16:38:09 and look at this: 2 $
I was evaluated at Fri, Mar 27, 2015 16:38:11 and look at this: 3 $
I was evaluated at Fri, Mar 27, 2015 16:38:12 and look at this: 4 $

Isso significa que PROMPT_COMMAND é avaliado no processo principal. Mas, usá-lo não é desejável para mim, porque eu geralmente o uso para outros propósitos e encadear isso não é conveniente (e só pode ser esquecido).

    
por midenok 27.03.2015 / 12:09

1 resposta

1

Use PROMPT_COMMAND . O que você está tentando fazer é exatamente o que é. Ele é expandido antes que o prompt seja avaliado. Se você quiser derivar parte do conteúdo do prompt desse código, defina variáveis em PROMPT_COMMAND , ative o promptvars variable e inclua essas variáveis em PS1 . Veja Função bash stateful e Exibir status de retorno não-zero no PS1 e especialmente Forçando um alias 'adicionado' a cada comando para exemplos.

Você pode alterar o estado do shell no prompt por meio da expansão aritmética, mas só é possível alterar variáveis inteiras dessa maneira. O resultado da expansão aparece no prompt, embora você possa ocultá-lo.

shopt -s promptvars
PS1='${nonexistent_array[$((counter+=$(calculate_increment)))]}…'

Encadear PROMPT_COMMAND é muito simples: para adicionar algo a ele, adicione uma nova linha e, em seguida, o comando que você deseja executar.

    
por 28.03.2015 / 02:35