Page 1 of 1

Possible to display the time on execution of any command automatically

Posted: 2021-Jul-25, 1:03 pm
by MigrationUser
23 Sep 2008 22:14
barbituate


Is it possible for some kind of wrapper or built-in bash function to automatically display the time (maybe right-justified) whenever a command is executed.

I do a lot of testing, and it helps to know when I kicked something off so I can quickly, at a glance, know how long it's been running.

The \t and \T options only show the time when the prompt was *displayed*, not when a command was executed. So seconds or minutes may have gone by between prompt-display and command execution.

I'd like it to look like the following:

$ ls 09:43:25
file1 file2 file3

$ cd /tmp 09:45:17

$ pwd 09:45:23
/tmp

So, I guess I'm asking is there something similar to "PROMPT_COMMAND" that lets me run a command on execution, not whenever the prompt is displayed? Or a homegrown solution that'd do the following:

- Catch the enter/return key so a newline doesn't happen
- Determine the width of the terminal
- spit out the date so that it appears on the right hand side of the terminal window
- add a newline
- run the command

Thanks!

----------------------------

#2 23 Sep 2008 23:04
Simon Sheppard


I don't know of anything that would do exactly that, but take a look at the screen command

https://ss64.com/bash/screen.html

It lets you manage multiple processes and the 'monitor' and 'info' options may be what you need.

----------------------------

#3 21 Jul 2011 01:09
flabdablet


In bash, you can do exactly what was asked for using key bindings:

Code: Select all

bind -x '"\C-xt":printf "%${COLUMNS}s\r" $(date +%T)'
bind '"\C-m":"\C-xt\C-j"'
This is kind of inscrutable, so let's pick it apart piece by piece.

bind -x keyseq:command binds a key sequence to a shell command. keyseq:command has to be a single argument, so it's wrapped in single-quotes to stop the shell from eating all the special characters inside it.

keyseq in this case is "\C-xt" which means "Control-X followed by t".

command is printf "%${COLUMNS}s\r" $(date +%T) which means "print the current time, right-justified in a field of width COLUMNS, followed by a carriage return character but no newline". And COLUMNS is an environment variable where bash keeps the width of the terminal it's running in.

So after entering this bind command, you can make the current time appear at the right hand side of the line you're currently editing by typing Control-X, then t.

The second bind command doesn't have -x, so it defines a macro: whenever you press Enter (which has the same ASCII code as Control-M), bash will see Control-X, then t, then Control-J (linefeed/newline). The first part of that (Control-X t) triggers the timestamp output we bound it to in the first step; the second, Control-J, enters the command line we're editing.

Why? Here's a session pasted from a freshly opened terminal on my computer:

Code: Select all

stephen@jellyshot:~$ bind -q accept-line
accept-line can be invoked via "\C-j", "\C-m".
stephen@jellyshot:~$ bind -x '"\C-xt":printf "%${COLUMNS}s\r" $(date +%T)'
stephen@jellyshot:~$ bind '"\C-m":"\C-xt\C-j"'
stephen@jellyshot:~$ bind -q accept-line                                10:01:27
accept-line can be invoked via "\C-j".
stephen@jellyshot:~$ 
Look up man bash and help bind for all the gory details.

----------------------------

#4 21 Jul 2011 07:26
Kustom42


The previous post will work but in my opinion the best way to accomplish this is to modify your $PS1 prompt. The PS1 prompt is one of many but is the primary one used when you are running commands in a bash terminal. I have included one of my favorite PS1 prompts below so you can see an example.

In this example there is a date/time stamp in the upper right hand corner of my terminal that updates anytime a command is run. It also modifies the colors to make it easier to read on my eyes. Do some searching on PS1 prompts and review the below one and you should find a good solution. The best way to implement this is of course appending this to your .bashrc file located in your home directory.

Code: Select all

export PS1="\[\033[s\033[0;0H\033[0;40m\033[K\033[0;36m\t\033[0;37m\033[u\]\[\033[0;37m\]<\u@\h \W>\$\[\033[0;36m\] "
And heres a link to the IBM site with an explanation of the PS1 prompt commands/ASCII escape codes.

http://www.ibm.com/developerworks/linux ... ip-prompt/

Last edited by Kustom42 (21 Jul 2011 07:26)

----------------------------

#5 21 Jul 2011 08:54
flabdablet
barbituate wrote:

The \t and \T options only show the time when the prompt was *displayed*, not when a command was executed. So seconds or minutes may have gone by between prompt-display and command execution.
...
So, I guess I'm asking is there something similar to "PROMPT_COMMAND" that lets me run a command on execution, not whenever the prompt is displayed?
To prove that messing with PS1 does not satisfy this requirement, try the following:

Code: Select all

PS1='\t$ '
bind -x '"\C-xt":printf "%${COLUMNS}s\r" $(date +%T)'
bind '"\C-m":"\C-xt\C-j"'
Here's a session that shows the result of me doing that:

Code: Select all

vmadmin@vmhost:~$ PS1='\t$ '
17:31:08$ bind -x '"\C-xt":printf "%${COLUMNS}s\r" $(date +%T)'
17:31:08$ bind '"\C-m":"\C-xt\C-j"'
17:31:12$ ls /tmp                                                       17:31:24
mnt-12200  mnt-18139  mnt-19420  mnt-21877  mnt-24095  mnt-26378  mnt-7347
mnt-12305  mnt-18576  mnt-19463  mnt-22005  mnt-24360  mnt-5182   mnt-7379
mnt-17881  mnt-18690  mnt-20913  mnt-23218  mnt-25093  mnt-5265
mnt-17921  mnt-18800  mnt-21264  mnt-23657  mnt-25845  mnt-5295
mnt-18101  mnt-19307  mnt-21362  mnt-23916  mnt-26117  mnt-5316
17:31:24$
As you can see, I waited a few seconds before typing in the ls /tmp command. The timestamp in the prompt is twelve seconds earlier than the one that appeared when I hit Enter.