2

I want to put duration of last running command in command prompt, f.ex:

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

Also, I want duration to not show up if it is less than some minimum threshold (say 30 seconds).

To achieve this I could put function call into PS1:

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

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

The problem is: print_duration() will be evaluated inside subprocess which will prevent changing the environment variables of main interactive bash.

Though I didn't realize the code from above I'll give a simpler example, cut & paste this to command prompt:

prompt_var=0

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

PS1='$(test_prompt)\$ '

And here is the result:

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 $

Note, that actually test_prompt() did evaluated in main process context just one first time (I suppose to check validity of function). But for actual prompt display it does this in subprocess (which is not really neat).

Though if I set PROMPT_COMMAND as was suggested in commentary:

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 $

This means that PROMPT_COMMAND is evaluated in main process. But, using it is not desirable for me, because I often use it for another purposes and chaining it is not convenient (and just can be forgotten).

midenok
  • 583

1 Answers1

1

Use PROMPT_COMMAND. What you're trying to do is exactly what it's for. It's expanded before the prompt is evaluated. If you want to derive some of the prompt content from that code, set variables in PROMPT_COMMAND, turn on the promptvars variable, and include these variables in PS1. See Stateful bash function and Display Non-Zero Return Status in PS1 and especially Forcing an 'added' alias to every command for examples.

You can change the shell state in the prompt via arithmetic expansion, but you can only change integer variables this way. The result of the expansion appears in the prompt, though you can arrange to hide it.

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

Chaining PROMPT_COMMAND is very simple: to add something to it, add a newline and then the command you want to run.

  • @mikeserv - sorry, I can't accept the answer, because it explicitly recommends to use PROMPT_COMMAND and it will be redundant for the described task. Though your clue about setting variable inside PS1 is very good and gives real solution to the problem! – midenok Mar 30 '15 at 11:13