10 ms·
When did I run that command? Update your Bash prompt with the command start time
- countermeasure 6y agoFor years I wanted a Bash prompt which would show when a command actually ran. I don't mean that it would show the time when the prompt was written to the terminal. That's easy. I mean that it would show the time when the command entered at it was executed. Those two times can be very different. This little hack updates your Bash prompt with the current time when you execute a command. As someone who spends many hours every day in the terminal, it's improved my life. Maybe it can help you too.
- kortex 6y agoHave you tried zsh with histdb? It's been an absolute gamechanger. Having a complete, precise, and effectively infinite history is like a second brain. I know not everyone is on the zsh train, but it might be able to be ported to bash (it's just pre-hooks and some sqlite) https://github.com/larkery/zsh-histdb https://github.com/larkery/zsh-histdb
- countermeasure 6y agoBash is the only shell I've ever used, but one day when time permits I'm looking forward to taking zsh for a test drive.
- deadbunny 6y agoA quick Google turns up this [1]. Haven't verified it works though. 1. https://github.com/thenewwazoo/bash-history-sqlite https://github.com/thenewwazoo/bash-history-sqlite
- kortex 6y agoOh! I actually used this before switching to histdb. IIRC it works-ish but there was less polish than histdb.
- jjt-yn_t 6y agostarted using it. Thanks.
- nicwolff 6y agoThis is handy, but if you just want the ability to see when you ran a previous command you can add export HISTTIMEFORMAT="%d/%m/%y %T " to your .bashrc and then history will show the date and time before each command that was run.
- ansible 6y agoI had no idea! I was about to try out the linked article, but this is all I really need. Excellent!
- countermeasure 6y agoI recommend using both approaches together. With an updating prompt, you can see when a command ran without having to type 'history'. And adding a date/time stamp to history is very useful when you need to go back further - hours, days or months.
- countermeasure 6y agoExcellent point. Seeing when a command in the history list was run is very useful. My preference is just for a date in the history, rather than date and time. I find that when I'm searching history, date is usually granular enough for me, so I can omit the time and save a little bit of screen real estate.
- blago 6y agoI've had this for a while and I noticed at least two problems on my mac: 1) It made the history command run much, much slower (I have HISTSIZE=100000) 2) Dates tend to reset to a uniform but meaningless value. I think it's related to OS reboots.
- kyuudou 6y agoI'm sure most know this but if anyone thinks this is a way of doing forensics, keep in mind it can be easily skipped over by doing a non-standard logout, like "kill -9 $$" or if a remote ssh connection gets cut for whatever reason. The command history for a session won't get written until logout by default. A workaround such as forcing each entry to be written to a log file will have to be done to have better assurance of true history.
- deleted 6y ago[deleted]
- tiny_epoch 6y agoI've had the following in my ~/.bash_profile for quite some time. I leave it here in the hopes it help someone. ## History configuration, see HISTORY in bash(1) ## builtin fc, aka fix command, for history manipulation ## fc [-e ename] [-lnr] [first] [last] ## -e or invoke editor ename; defaults to $FCEDIT ## -l or list commands ## -n or suppress entry numbers ## -r or reverse command order ## first, last selects a range of entries by numeric index ## ## fc -s [pat=rep] [cmd] ## -s or substitute all occurences of pat with rep # # - h() is short for history # - r() is short for replay # - always append to the history, don't overwrite # - save multi-line commands in a single entry # - insist on vim everywhere # - don't record commands with a leading space or duplicates # - constrain the size of the history file # - ignore common things # - constrain the number of history entries # - set up nicer timestamps alias h="history" alias r="fc -s" shopt -s histappend shopt -s cmdhist export FCEDIT=$EDITOR export HISTCONTROL=ignoreboth export HISTFILE=$HOME/.bash_history export HISTFILESIZE=1048576 export HISTIGNORE='ls:ls -l:ls -latr:ps -ef:fc:h:history:clear:exit' export HISTSIZE=8192 export HISTTIMEFORMAT='[%F %T] '
- chrisweekly 6y agoThanks, @tiny_epoch -- that was helpful. :)
- pronoiac 6y agoIn iTerm2 on Macs, command-E shows timestamps of lines in an overlay, with dates and down to the second.
- yen223 6y agoIt's cmd-shift-E on my version of iTerm2. Not sure if they changed it at some point.
- memco 6y agoWhat’s nice about iterm2’s approach is it shows it for every line of output not just commands, but even before I started using that I had a timestamp on the right hand side of my fish prompt so I can track the progress of my work. Don’t use any thing like this in bash, but there are definitely times when I remote into a system where having them would be handy.
- dharmab 6y agoI use this feature a lot when writing timelines in postmortems.
- macintux 6y agoThank you! That's a great tip. (For me it's ⌘-Shift-E).
- 6y ago
- awinder 6y agoI switched over to zsh a few months back and picked up something like this method: https://gist.github.com/zulhfreelancer/9c410cad5efa9c5f7c74cd0849765865 https://gist.github.com/zulhfreelancer/9c410cad5efa9c5f7c74c.... This is nice to see for bash and I definitely agree on the usefulness notes, it’s been a nice improvement / helped me not get confused a few times
- mikelward 6y agoIsn't that printing the time the prompt was printed (the time the previous command finished)? This is printing the time you pressed Enter (the time the command started), which is harder and less common, since that's not when the prompt is printed.
- mikelward 6y agoThis is one way you could do something similar in zsh: https://stackoverflow.com/a/17915260/102182 https://stackoverflow.com/a/17915260/102182
- countermeasure 6y agoIt looks like zsh can handle updating the time in the prompt quite simply and elegantly.
- mikelward 6y agoYes, I find that solution much simpler.
- Symbiote 6y agoIt keeps the clock up-to-date, but I use Konsole's "monitor for activity" feature, which changes the colour of inactive tabs if there is output. Instead, this seems to work: TRAPDEBUG() { case "$WIDGET" in zle-line-finish) zle reset-prompt ;; *) ;; esac } (I don't know if further cases will be required.) This updates the prompt after "enter" is pressed, but before the command is executed.
- Bnshsysjab 6y agoI wrap every interactive shell in ‘script’ effectively recording it. I’ve been tempted to add time logging by something similar to PS1=“$(date)\r$PS1” Because I don’t really care about the execution time of current commands but might care historically.
- countermeasure 6y agoIf I'm understanding it correctly, what this sort of approach will give you is a timestamp in the prompt which is generated when the prompt is printed to the terminal and then doesn't change. The thing is that the prompt might sit there for minutes or hours before you use it to run a command, so that timestamp doesn't reliably serve as an accurate record of when a command was run. That's the problem which my approach addresses by updating the timestamp when a command is run.
- Bnshsysjab 6y agoSure, forensics accuracy isn’t something I hugely care about, i do have some shell sessions that span days so having an indication can be handy. If I did, It’s also possible to get amount of time a command required to complete. Based on that execution time in conjunction with the timestamp of the next print of PS1 it would be easy to deduce the time when a line was actually executed, rather than when typing of the line began, but at that point I’d probably just record my screen to track any harder to determine behaviours.
- Normal_gaussian 6y agoIf you also write the starttime to a file you can read it and produce the elapsed time. Then one step further is to have a program read all your ongoing times alongside parsing the active processes, and give you running progress of your current shells. Mine works but is hacky, it would be nice to have a more neatly packaged solution.
- countermeasure 6y agoI think that hacks are the name of the game when it comes to this sort of thing with Bash, so don't feel bad about that. My solution is very much a hack too.
- mbreese 6y agoAnd I like storing the time the prompt was printed so that I can keep track of how long a command took. When I care to keep track of when a command started, I just hit enter once or twice to get a “fresh” timestamp, then I have both an accurate start time and an accurate stop time. This is very handy if you run long jobs in a tmux session, for example. If I rewrote the prompt each time I ran a command, I’d lose that record. (I suppose I could do the same trick in reverse and if I care to know how long a command will take, I could run it and hit enter a few times to queue up an empty command to create the same timestamp effect after the fact).
- countermeasure 6y agoI'm not sure how it would suit your workflow, but you could try out PROMPT_COMMAND. https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-PROMPT_005fCOMMAND https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.... It's executed just before the PS1 prompt is printed. A nice idea I've seen is to use PROMPT_COMMAND to print the time a command finished (and maybe an indication of its exit status) in low-contrast text at the far right of the terminal. Then that info is there if you want to look for it, but it's not distracting. Then you could have the best of both worlds, and it would all happen without the need to remember to create fresh prompts.
- mkl 6y agoI think you could do the same thing but put the real time in place of --:--. Then when the command is run, overwrite the time with the current time. You'd only be able to see the time the most recent command took with precision, but that's usually what matters.
- hunter2_ 6y agoAll these neat tricks being discussed, and meanwhile I just `date; my_cmd; date` for jobs I want start/end times of. The fact that I can do it with no configuration on all the umpteen boxes I log into is the reason I stick with it.
- fizixer 6y agoor, if you're only interested in the time it took for the command to run: time my_cmd
- alpaca128 6y agoAll of those are only useful if you thought of it beforehand. Which is rare in my experience, often I want to know the time exactly when something unexpected happened.
- derision 6y agoMost of the time I needed to know when I ran a command, I didn't know I would need it at the time I ran
- stragies 6y agoI have this in my "~/.inputrc": ".,d": "\C-adate; \C-e; date\n" Whenever I want a command dated like in your suggestion, instead of pressing Enter to execute the command, I press the key-sequence ".,d" and the command gets wrapped in 'date' calls.
- sdegutis 6y agoIf you're using zsh and have a date like %D{...} in your prompt, set TMOUT=1 and define TRAPALRM to run `zle reset-prompt` and your date will auto-update. Full prompt at https://github.com/sdegutis/dotfiles/blob/master/.zshrc#L3-L19 https://github.com/sdegutis/dotfiles/blob/master/.zshrc#L3-L... fwiw.
- graton 6y agoSort of related, I like to put this snippet in my PROMPT_COMMAND variable: PROMPT_COMMAND='echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(HISTTIMEFORMAT= history 1)" >> ~/.logs/bash/bash-history-$(date "+%Y-%m-%d").log' I forget where I learned this. What it does is write the bash history to a log file, with the date/time, directory of the command, and the command. Occasionally it has helped me find where a file is that I was working on :)
- envolt 6y agoI do this on iTerm CMD + Shift + E Is it the same or something different?
- acqq 6y agoAnd I discovered that I like to always see in the prompt the return value of the last command executed, if it is not 0. nd that I don't need the name of the machine and the user name in the prompt on my main computer.
- vietjtnguyen 6y agoI just write all my commands to a log. It's saved me a number of times. https://spin.atomicobject.com/2016/05/28/log-bash-history/ https://spin.atomicobject.com/2016/05/28/log-bash-history/
- varenc 6y agoYou can do this easily with zsh’s standard features. I love having years of my command history! It's all combined across sessions and instantly searchable with the standard ^R. These are most of the settings in ZSH I use to enable all that. HISTSIZE=10000000 SAVEHIST=10000000 setopt EXTENDED_HISTORY # logs the start and elapsed time setopt INC_APPEND_HISTORY setopt SHARE_HISTORY setopt HIST_IGNORE_DUPS setopt HIST_IGNORE_ALL_DUPS setopt HIST_FIND_NO_DUPS Apple now even recommends zsh shell over bash! =) https://support.apple.com/en-us/HT208050 https://support.apple.com/en-us/HT208050 (it's the 10.15 default)
- MachineGunPablo 6y agoyes, `EXTENDED_HISTORY` is all you need... And BTW I think HIST_IGNORE_DUPS` is not needed if you set `HIST_IGNORE_ALL_DUPS`
- kinleyd 6y agoThank you, this was so timely. My zsh terminals have been saving my command history but, for reasons I didn't know, were not displaying them. I'm much pleased to have that sorted out.
- TwoNineFive 6y ago> Apple now even recommends zsh shell over bash! Worth reading why they did that: https://thenextweb.com/dd/2019/06/04/why-does-macos-catalina-use-zsh-instead-of-bash-licensing/ https://thenextweb.com/dd/2019/06/04/why-does-macos-catalina...
- dmortin 6y agoYes, it's useful. It's even better if you can search your commands with out of order matching (multiple words in any order). I do this from Emacs (you can use Helm or Ivy, for example) and it's extremely convenient and effective to quickly get old commands back.
- question11 6y agoAS400 had this..! all commands logged to a sql style database and a way to revert them (a revertible rm -rf *). Very cool
- dummytummy 6y agoHmm
- deleted 6y ago[deleted]
- naggie 6y agoI do something similar -- I show the duration of the command in a human readable format, but only if the command too more than 60 seconds; useful to get an idea of how long compilations (etc) take See https://github.com/naggie/dotfiles/blob/master/home/.functions.sh#L148 https://github.com/naggie/dotfiles/blob/master/home/.functio... One of my most useful changes is a script that garbage-collects my history file: deduplication, removal of sensitive + trivial commands. In combination with a FZF based history search that's shared between all shells, I effectively have a super-quick database of every command without any noise. See https://github.com/naggie/dotfiles/blob/master/scripts/cleanup-history https://github.com/naggie/dotfiles/blob/master/scripts/clean... -- added via bash/zsh hooks.
- MachineGunPablo 6y agowhy would you write an own script to sanitize your history manually? that sounds crazy, you can disallow duplicates and blacklist specific commands using normal shell configuration...
- naggie 6y agoBecause HISTCONTROL=ignoredups only deduplicates sequential commands, and having my own script allows specification of the blacklist in a non-redundant way between zsh and bash. In addition, I can do it in such a way that the most recent invocation is deleted last. I can also use regexes. See https://github.com/naggie/dotfiles/blob/master/scripts/cleanup-history#L11 https://github.com/naggie/dotfiles/blob/master/scripts/clean... for more reasoning.
- MachineGunPablo 6y agozsh, HISTORY_IGNORE is a regex what are you talking about... and there is history_ignore_all_dups so I'm really not following...
- naggie 6y agoNot in bash. Like I said, I use bash (and sometimes ZSH)
- b0rsuk 6y agoI think it would be more useful to know where did I run the command. That bit of context is often lost unless you use absolute paths a lot.
- stragies 6y agoadd this to you "~/.inputrc" : "\C-xj": "\C-e\C-u # `pwd`\e\C-e\C-a\C-y\C-j" Whenever you want a command saved with the launch directory, instead of Enter, press "CTRL-x j"
- b0rsuk 6y agoWhy not make it default?
- deleted 6y ago[deleted]
- neurostimulant 6y agoThe "mortalscumbag" theme from oh-my-zsh show current path above the prompt line which is exactly what you want. Can't live without it! I enable it on every system I use.
- lotia 6y agoThanks for sharing this guide. For those (like me) who are lazy and want to delegate the hard work and maintenance to folks smarter than me, starship is a cross-shell prompt that will print duration of commands. https://starship.rs/ https://starship.rs/
- ducktective 6y agohttps://starship.rs/config/#command-duration https://starship.rs/config/#command-duration
- albertzeyer 6y agoIn our research group (with shared NFS), we log the history per directory (i.e. the histfile is $PWD/.history.$USER), and we also log the date/time. This has been extremely helpful. Not only checking your own history, but also being able to see others history. E.g. imagine going through some directories of some former colleague who is gone now. Otherwise it would often be impossible to really understand how sth was created, or ended up that way, etc. I mean, properly documenting everything is of course nice, but even if that is done consistently, it will still miss some details. And in practice, it never is done consistently. I wonder why this is not more standard. Most shells write a single global histfile to $HOME.
- sdoering 6y agohow do you configure this? I would love to use this.
- albertzeyer 6y agoIt's a very custom solution. For Bash, in ~/.bashrc: export PROMPT_COMMAND="myLocalHistory" # we don't need everything within the history alias useHistory='grep -E -v "^ls$|^ll$|^l$|^dir$|^cd |^bg$|^fg$|^qstat |^note |^mutt|^std|^clear$|^qinfo$|^gh|^qw$" | wc -l' function myLocalHistory() { HISTORYLINE=`history | tail -1 | sed 's:^ *[0-9]* *::g'` if [ `echo $HISTORYLINE | useHistory` == 1 ] ; then ((date +%F.%H-%M-%S | tr -d '\n' ; echo " $HISTORYLINE") >>.history.$USER) 2>/dev/null fi } For ZSH, in ~/.zshrc: preexec () { ~/dotfiles/system-tools/helpers/local-history-add.py $1 >/dev/null } For Fish, in ~/.config/fish/config.fish: function fish_preexec --on-event fish_preexec ~/dotfiles/system-tools/helpers/local-history-add.py $argv & end The script local-history-add.py is here: https://github.com/albertz/helpers/blob/master/local-history-add.py https://github.com/albertz/helpers/blob/master/local-history... The Bash solution probably could also be simplified by using this script, which takes care of filtering logic and adding it to the history file, in your preferred format.
- akavel 6y agoI have a much shorter snippet in .profile for bash: if $INTERACTIVE; then # http://superuser.com/a/175802 # show date when command was executed preexec() { [ -n "$COMP_LINE" ] && return # do nothing if completing [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND echo -ne "\033[$(( COLUMNS-15 ))C$(date +'%m%d-%H:%M:%S')\r" } trap 'preexec' DEBUG fi The `echo -ne ...` is what prints the date (month+day+time, year is assumed obvious) close to the right margin (COLUMNS-15), then prints `\r` to get back to left margin. This has pros (less space taken) and cons (shows up in copy&paste), you can surely edit the format to your liking if you prefer. I'll have to check how the OP's PS0 compares with that however, maybe it can make my snippet even simpler? edit: Ah, IIUC, PS0 seems bash 4.4+, for better or worse: https://github.com/rcaloras/bash-preexec/issues/28 https://github.com/rcaloras/bash-preexec/issues/28
- ddevault 6y agoI do something similar, but I print uptime instead of wall-clock time. https://git.sr.ht/~sircmpwn/dotfiles/tree/master/bin/prompt.go https://git.sr.ht/~sircmpwn/dotfiles/tree/master/bin/prompt....
- aembleton 6y agoBob the fish theme gives me this and places it on the right hand side of the prompt: https://github.com/oh-my-fish/theme-bobthefish https://github.com/oh-my-fish/theme-bobthefish
- ChrisMarshallNY 6y agoIt's pretty cool. I probably won't use it, because it's rather "heavy," and I don't really need it, but I like. I suspect that we'll be seeing a lot more of these kinds of things, coming out of this "house arrest" situation.
- x3n0ph3n3 6y agoI found the requirement for shopt -s histverify unbearable. I use !! extensively and don't want to hit enter twice.