50

I prefer to use terminal and spend most of the time using it. I am searching a way to see time in terminal while I use it parallel. The time would change automatically when it passes. It would be awesome if it would display left to my command prompt.

If this is my command prompt in terminal:

saurav@saurav-P4I45Gx-PE:~$

Then I would like to see clock(time) as:

saurav@saurav-P4I45Gx-PE[06:27:01]:~$

or

saurav@(06:27:01):~$

or any other format. where 06:27:01 is the time. What I want is just to show the time which changes when seconds pass.

So is there any way to achieve this?

8
  • You might be able to set the $PS1 (prompt) variable to have the time, but I'm not sure if changes.
    – kiri
    Oct 17, 2013 at 1:32
  • You can specify \@, but the time will only be recalculated each time the prompt displays, not a current time.
    – kiri
    Oct 17, 2013 at 1:40
  • 2
    @muru, As I specified in my question, that answer only work for zsh not for bash.
    – Rosh_Th
    Sep 20, 2014 at 7:31
  • 2
    But the question itself is not about zsh (it is general), so I advised G_P to post the answer there. With G_P's answer now added there, it qualifies as a dupe.
    – muru
    Sep 20, 2014 at 7:32
  • 1
    @muru that other question specifically wants the time in the prompt. The OP here just wants it printed in the terminal and does not specify that it has to be in the prompt.
    – terdon
    Sep 20, 2014 at 11:46

11 Answers 11

95

I'm not sure that is so simple to achieve this using the default bash shell (but I'm not saying that it's impossible). You will probably need a command/function which is able to refresh the command prompt every second without interfering with anything you type on the prompt.

The Z shell (zsh) has a built-in command, called zle, which, when used with the reset-prompt argument, forces the prompt to be re-expanded, then redisplays the edit buffer.

If you want to try it, use the following steps:

  1. Install Z shell with this command:

    sudo apt-get install zsh
    
  2. When you run zsh for the first time, choose 0 when you are asked.

  3. Edit the ~/.zshrc file and add the following lines:

    setopt PROMPT_SUBST
    PROMPT='%B%F{red}%n@%m%f%F{yellow}[%D{%L:%M:%S}]%f:%F{blue}${${(%):-%~}}%f$ %b'
    TMOUT=1
    
    TRAPALRM() {
        zle reset-prompt
    }
    

    Save the file and close it.

  4. In your terminal, when you are still using zsh, run source ~/.zshrc, or simply zsh, to reset your prompt. Now your prompt should look like:

    saurav@saurav-P4I45Gx-PE[1:25:21]:~$
    

    with some colors.

  5. If you like it, run chsh -s /bin/zsh to change your current shell to /bin/zsh (a re-login is required for this change to take effect).

  6. Run exit if you want to exit from zsh shell.

Here is a 15 second screencast from my terminal:

running clock in terminal before the command prompt

7
  • 6
    Bonus points for screencast. Cool stuff indeed.
    – MadMike
    Oct 17, 2013 at 11:28
  • @SauravKumar Run chsh to change your default shell from /bin/bash to /bin/zsh. You have to log out and log in again. Oct 17, 2013 at 11:34
  • Actually I've made it.. But every-time terminal opens I've to execute zsh command to enter into this clock mode.. Oct 17, 2013 at 11:36
  • @RaduRădeanu: Yes worked after login as well as restart.. You're great.. Jai Ho!! :P Oct 17, 2013 at 11:44
  • This does not work for me. After one second, it closes the terminal. I'm in Linux Mint, but I didn't think that would matter since I still use zsh. Any ideas?
    – istrasci
    Mar 27, 2016 at 21:55
39

If you want to display running time in your terminal you can use this command. It will display time in the upper right side of your terminal.

  while sleep 1;do tput sc;tput cup 0 $(($(tput cols)-11));echo -e "\e[31m`date +%r`\e[39m";tput rc;done &

enter image description here

But note that displaying time using this command sometime may overlap the text present in terminal. So use this command with little caution.

Another way may be using control character in in the PS1

[guru@guru-pc ~]$  PS1='\[\u@\h \T \w]\$'

[guru@guru-pc 11:06:16 ~]$

But in this method your time will refresh only after pressing enter.

If you want to above method permanent add the above command(the one you like or both) in your ~.bashrc file.

4
  • Great! Any clues as to how to change the colour of the clock? Feb 27, 2018 at 19:53
  • 1
    @CalculusKnight, you can change color code in the command. You can refer this for color code.misc.flogisoft.com/bash/tip_colors_and_formatting
    – g_p
    Feb 27, 2018 at 19:58
  • 1
    This works PERFECTLY - thank you very much. I'm calling it from .bashrc to stop an overly-proactive firewall from killing idle SSH connections.
    – Criggie
    Mar 6, 2018 at 21:56
  • This is a great solution that does not require installing zsh. Jul 27, 2020 at 19:15
14

If all you want to do is show a clock, just use date:

while :; do date +%r; sleep 1 ; done

That will show the time every second until you stop it with CtrlC. If you want it to be on the same line (the above will print a new line every second), do this instead:

while :; do printf '%s\r' "$(date +%r)"; sleep 1 ; done
1
  • Thanks, I was looking for it. But when using it to debug a tunnel, the cursor stays at the beginning of the line, therefore it gets overwritten when tunnel is closed. I solved changing it this way: while :; do printf '\r%s ' "$(date +%r)"; sleep 1 ; done
    – Kar.ma
    Mar 15, 2021 at 10:39
3
export PS1='\t$'

since i prefer displaying as little background info as possible on the terminal i generally customize every session as a #, $, etc. (if you want to change it permanently, minerz029's solution is perfect)

To modify it to show current, I could go for

export PS1='\T$'

for time in 12 hour format. You can view the bash documentation for other options.

2

This question has been bothering me for a few days, and here's my edited post with all the material I've learned. Specifically , my goal was to achieve showing clock next to prompt in BASH. Just like Radu Radeanu mentioned in his answer, the key is to find a function or variable what is able to constantly refresh the command prompt or redraw the screen, without interfering with your screen or with whatever you type. While, this is possible to achieve with while loop, as shown by G_P, the constant redrawing of the screen with tput function messes up with whatever text is on my screen at the instant it refreshes. I've come pretty close to achieving what the OP asked by modifying somewhat the code G_P posted , but still I believe Radu's answer is the closest to what OP wants. Without further ado, here's some of the things I've learned, presented for your judgement.

#1, My preferred solution: Terminal Multiplexer

Terminal multiplexer is a software that allows splitting the terminal screen into two or more screens. In particular, I want to draw attention to Byobu terminal. This ncurses based terminal emulator, allows you to show time, CPU percentage, memory, and whole bunch of other indicators. In the screenshot from my byobu terminal you can see cpu temperature, battery percentage, internet connection quality, CPU frequency, RAM, date, and of course time. If you're mostly concerned with constantly monitoring these things while in terminal, Byobu is the way to go. In fact , I've come to like it so much, I've set it to automatically load while login into tty. The only quirk is that in tty you can't actually merge the separate windows - only switch between tabs with F3 and F4 keys.

Screenshot of my byobu terminal

An alternate solution involving multiplexing windows is by using splitvt, which splits the screen into two parts. You can run a terminal clock such as tty-clock , use watch command with date, or you can code one yourself with a script. More on that later. In the screenshot you can see one part of the split with normal bash prompt on top, and in the lower one you can see a script running, that just constantly refreshes output of date command with clear command.

enter image description here

#2 , While Do Loop and tput This is probably the closent to what the person who asked the question wanted implemented with bash.

G_P has posted a great solution involving the while do and tput commands. However in G_P's code there were two things I didn't like. One, the clock was to the right of the prompt, and two - because sleep cycle is 1 second (refer to the original code where it says sleep), the screen is redrawn every second, and that messes up my output. What I did, is to edit my bash prompt to be one line lower with \n operator and change G_P's code so that tput operator would position the clock right above the prompt, and refresh every 60 seconds; that allows me to see hours and minutes (and I don't exactly care about minutes), while the clock's loop doesn't mess up my screen. First, here's my prompt:

PS1='${debian_chroot:+($debian_chroot)}\n[*\u@Ubuntu*]\n $(date) :\w\$  ' 

And here's G_P's modified code: enter code here

 while sleep 60;do tput sc;tput cup 0 0;date +%R;tput rc;done &

Small edit: I've noticed that this code above doesn't bring up the clock right away sometimes. Here's a better version: while true; do tput sc;tput cup 0 0;date +%R;tput rc; sleep 60; done & This one places clock on screen first, then lets bash know to go through sleep cycle of 60 second

Note, the tput cup 0 0 places clock into upper right corner of the screen, right above my prompt and sleep 60 changes sleep cycle to 60 seconds, because that way I can monitor only hours and minutes instead of every second. This way, whatever text i have on the screen isn't affected, for the most part (only when i happen to run a command the same time clock refreshes).

enter image description here

PS1 line is already in your .bashrc profile, so you just need to tweak it a little. The while do loop should be added somewhere in the same file, preferably in the end with # comment that this is stuff you added initially. And don't forget to always back up any file like that just in case you make bubu and need to go back to the way it was.

#3, Scripting and other

This part is merely for those who want to see time. For those who want to constantly monitor it, #1 and #2 are preferred options.

So as we already have seen the while do loop is pretty useful. Here's how you can create a clock with while do loop, date, and sleep commands.

enter image description here

Hit return/enter, and you basically will see output of date command shown on cleared screen every second. If you don't want to type all that every time, turn all this stuff into script:

#!/bin/bash

while true
do
clear;date
sleep 1
done

Now you can run that script with splitvt in one instance of bash, while working in the other.

Another solution is watch -n1 date command, which will continuously execute date command with period of 1 second.

In Conclusion: I've learned some things while trying to find the answer to this question, and I hope my findings helped you in some way, and I hope I was able to contribute on this question. Byobu terminal IMHO is the best solution, but decide for yourself, make some research, and choose whichever way works best for you.

Some of the things I've found while researching:

My original post, the minimalistic solution: Edit your ~/.bashrc file. I prefer editing it with nano, so

nano ~/.bashrc

Here's the portion of my own edited file:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\$'    
else
   # PS1='${debian_chroot:+($debian_chroot)}[*\u@Ubuntu*]:\w\$ '
    PS1='${debian_chroot:+($debian_chroot)}[*\u@Ubuntu*]\t:\w\$ '
fi

After else statement the first line is commented out with # (this is my old prompt), now the second line is the one you want, and specifically \t operator. That shows running time in 24 hour format. For more info check out this . Also a small note, I'm using the stuff after else, because i'm not using colored prompt.

PS: Please let me know if I should add anything to my answer or edit it in any way, but for the most part i believe this is most conclusive answer i could come up with, and at least I personally won't be adding anything new to it.

1
  • 1
    This won't display a 'running' clock as the OP wants. It will just add the time to the terminal prompt.
    – Parto
    Sep 20, 2014 at 8:36
1

This time will only change when a new prompt is executed

You can add the following to your .bashrc:

export PS1="\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:[\t]:\w\$ "

Which will produce:

USER@HOST:[12:59:59]:~$ _

More information here: http://www.thegeekstuff.com/2008/09/bash-shell-ps1-10-examples-to-make-your-linux-prompt-like-angelina-jolie/#8

Search for "8. Create your own prompt using the available codes for PS1 variable" in that above page.

9
  • 3
    I appreciate for your time and effort, but this is not what I want.. Oct 17, 2013 at 1:51
  • @SauravKumar Yes, I understand you want a running clock. I'm not sure if that's possible with the 'PS1' variable, maybe $PROMPT_COMMAND would work if you can find a command which displays ticking time.
    – kiri
    Oct 17, 2013 at 2:01
  • Well I think you can do this.. :) It seems that you've reached near to the solution.. Oct 17, 2013 at 2:07
  • why it includes \u two times ? @SauravKumar
    – David
    Jan 11, 2014 at 13:23
  • @David: I'm sorry, I don't know. But @minerz029 probably would answer your question. :) Jan 11, 2014 at 13:45
1

I really like the ncmpcpp clock feature, triggered by 0-key (see screenshot). For more detail on the installation procedure, please refer to this post.

enter image description here

1
  • 3
    watch -t -n1 "date +%T|figlet" would be an easy way.
    – g_p
    Sep 20, 2014 at 10:02
1

Influenced by g_p and Serg I tried to create function in bash. It works, but I'm not sure that it's a good idea to check ps command every second to see whether bash is a fg process or not

prompttime() {
  PSCOLGREEN="\[$(tput setaf 2)\]"
  PSCOLRESET="\[$(tput sgr0)\]"
  PS1="${PSCOLGREEN}\\$ ${PSCOLRESET}[--:--:-- \W] "
  [ "$PROMPTCURRTTY" ] || {
    PROMPTCURRTTYtemp=$(tty)
    PROMPTCURRTTY=${PROMPTCURRTTYtemp//\/dev\//}
    unset PROMPTCURRTTYtemp; }
  PROMPTSTATE="[S]s+"
  while :; do
    sleep 1
    [ "$(ps a | grep "${PROMPTCURRTTY}.*${PROMPTSTATE}.*$(basename $SHELL)")" ] &&
    { tput sc
      tput hpa 3
      echo -en "$(date +%T)"
      tput rc; }
    continue
  done&
}
1

If you never need to use debian_chroot then it's a handy place to put the time the command prompt was displayed by using:

export PROMPT_COMMAND='debian_chroot=$(date +%r)'

Type this in your terminal and watch your command prompt change with the time:

rick@alien:~$ export PROMPT_COMMAND='debian_chroot=$(date +%r)'

(09:14:59 PM)rick@alien:~$ 

After the time is set once, to get a running clock which updates every second use:

while sleep 1;do tput sc;tput cup $(($(tput lines)-1)) 1;printf `date +%r`;tput rc;done &

This .gif shows the commands in action:

Time terminal prompt.gif

0

Write a loadable builtin for bash a very powerfull way to compile bottlenecks in bash, anyways ...

A good entrance point to the topic is offered here

I called the loadable builtin reprompt and its source looks something as simple as the following:

...
#include "readline/rlprivate.h"

...

int
reprompt_builtin (list)
     WORD_LIST *list;
{
  rl_set_prompt (list->word->word);
  return (EXECUTION_SUCCESS);
}

...

struct builtin reprompt_struct = {
  "reprompt",    /* builtin name */
  reprompt_builtin,  /* function implementing the builtin */
  BUILTIN_ENABLED,  /* initial flags for builtin */
  "reprompt [prompt]",     /* usage synopsis */
  0      /* reserved for internal use */
};

Compile and install your loadable builtin. Use it as follows:

enable -f /usr/lib/bash/reprompt reprompt

function Login::ps () {
  declare -gx PS1="$(your_custom_ps_generator_function)"
}

export PROMPT_COMMAND="Login::ps"

trap 'Login::ps; reprompt "$PS1";' SIGWINCH

My experiments resulted: terminal resize prompt update preview

0

Influenced by g_p I made this command that requires toilet instead of figlet (Since I personally find toilet's text easier to read). I added some other things to it such as the date and timezone.

(Without nanoseconds or ISO)

watch -t -n0.1 "date +%rZone:[%Z]%n%A%n%b%d/%Y|toilet -t -s -W"

(With nanoseconds)

watch -t -n0.001 "date +%rZone:[%Z]%n%A%n%b%d/%Y%nN=%N|toilet -t -s -W"

(With ISO)

watch -t -n0.001 "date +%rZone:[%Z]%n%A%n%b%d/%Y%nISO=%V-%G|toilet -t -s -W"

(With both ISO and nanoseconds) (Requires smaller text to display correctly)

watch -t -n0.005 "date +%rZone:[%Z]%n%A%n%b%d/%Y%nISO=%V-%G%nN=%N|toilet -t -s -W"
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .