- RootUsers
- Guides, tutorials, reviews and news for System Administrators.
- 17 Bash History Command Examples In Linux
- How To Use Bash History – Command Examples
- 1. Print History
- 2. Print ‘n’ Lines
- 3. Repeat Most Recent Command
- 4. Repeat Specific Command
- 5. Repeat Command Starting With A String
- 6. Piping History
- 7. Write To History File
- 8. Clear History File
- 9. Delete Specific Line
- 10. Run Single Command Without Logging
- 11. Run All Commands Without Logging
- 12. Ignore Specific Commands
- 13. Increase History Size
- 14. Add Timestamps To History
- 15. Change History File Location
- 16. Do Not Store Duplicate Commands
- 17. Reverse Search
- Summary
- Share this:
- How can I see all of the bash history?
- 5 Answers 5
RootUsers
Guides, tutorials, reviews and news for System Administrators.
17 Bash History Command Examples In Linux
The ‘history’ command available in Bash can be used to simply display your shell history, however there’s also a whole lot more that you can do with it, which we’ll demonstrate here.
Bash history allows us to quickly see what has been executed previously on a system, allowing you to hold users at least somewhat accountable for their actions (more on this later). It’s also useful if you’ve run something before and forgot the command, I can’t begin to tell you the number of times that I’ve done this!
How To Use Bash History – Command Examples
1. Print History
In its most simple form, you can run the ‘history’ command by itself and it will simply print out the bash history of the current user to the screen. Commands are numbered, with older commands at the top and newer commands at the bottom.
[[email protected] ~]$ history 1 ip a 2 exit 3 ls -la 4 pwd [[email protected] ~]#
2. Print ‘n’ Lines
While the default is to print all history lines, you can specify a number after the history command to output this amount of the most recent lines.
[[email protected] ~]$ history 3 16 passwd 17 getenforce 18 history 3
3. Repeat Most Recent Command
[[email protected] ~]# date Sun Aug 28 03:14:55 PDT 2016 [[email protected] ~]# !! date Sun Aug 28 03:14:57 PDT 2016
4. Repeat Specific Command
As shown above, the bash history command displays line numbers. It is possible to repeat a command by specifying its line number.
[[email protected] ~]# history 2 101 date 102 history 2 [[email protected] ~]# !101 date Sun Aug 28 03:18:55 PDT 2016
5. Repeat Command Starting With A String
We can repeat the last command starting with a specified string. This is done with !string, where string is the start of a previously executed command.
[[email protected] ~]# systemctl start httpd [[email protected] ~]# systemctl stop chronyd [[email protected] ~]# systemctl restart chronyd [[email protected] ~]# !systemctl systemctl restart chronyd
As shown the most recent command that started with ‘systemctl’ has been run again. While useful, this can obviously be dangerous if the last command is actually different from what you expect. You can run this with ‘:p’ on the end to instead print the command rather than execute it straight away.
[[email protected] ~]# !systemctl:p systemctl stop chronyd
6. Piping History
We can of course pipe the output of the history command into many other useful commands, such as less or grep. When piping into less we can scroll through the output of the history file rather than having it all output to the terminal. By outputting to grep we can search for commands that have been run previously.
[[email protected] ~]# history | grep httpd 65 yum install httpd -y 106 systemctl stop httpd 107 systemctl start httpd 117 history | grep httpd
7. Write To History File
Usually the history file is written to upon logout, therefore if you have an SSH session that has timed out you will not have your history from that session when you log back in. We can force the current history to write to the users ~/.bash_history file with the -w option.
8. Clear History File
9. Delete Specific Line
Clearing the whole history file may be overkill, we can instead delete a specific line number from the history file with the -d option.
[[email protected] ~]# history | grep password 121 Sun 28 Aug 2016 03:33:11 AM PDT mysql -u root -p oops_this_is_my_password 122 Sun 28 Aug 2016 03:33:19 AM PDT history | grep password [[email protected] ~]# history -d 121 [[email protected] ~]# history | grep password 121 Sun 28 Aug 2016 03:33:19 AM PDT history | grep password 123 Sun 28 Aug 2016 03:33:29 AM PDT history | grep password
10. Run Single Command Without Logging
[[email protected] ~]# echo "secret command";history -d $(history 1) secret command
11. Run All Commands Without Logging
Additionally we can unset the history file variable for the current bash session which will prevent all history for the current session from being stored.
[[email protected] ~]# echo $HISTFILE /root/.bash_history [[email protected] ~]# unset HISTFILE [[email protected] ~]# echo $HISTFILE
Note that this is not permanent, when you log out and log back in HISTFILE will be reset back to the default. This example will allow you to have an unlogged session, though you could specify the unset in ~/.bashrc to never log history.
12. Ignore Specific Commands
We can specify a list of commands that should never be logged in the history file with the $HISTIGNORE variable, which is not set by default.
[[email protected] ~]# echo 'export HISTIGNORE="ls:cd"' >> ~/.bashrc
[[email protected] ~]# ls anaconda-ks.cfg new_history [[email protected] ~]# pwd /root [[email protected] ~]# cd [[email protected] ~]# echo hi hi [[email protected] ~]# history 5 123 history 124 du 125 pwd 126 echo hi 127 history 5
13. Increase History Size
By default 1000 lines of history will be stored, as per the values stored in the $HISTSIZE and $HISTFILESIZE variables.
[[email protected] ~]# echo $HISTFILESIZE 1000 [[email protected] ~]# echo $HISTSIZE 1000
The default for all users is stored in the /etc/profile file, this can be modified or you can otherwise append the following lines to the bottom of ~/.bashrc which will apply to that user at next login.
HISTSIZE=2000 HISTFILESIZE=2000
14. Add Timestamps To History
As you may have noticed by default we are not able to see the date and time that commands were executed, merely their order. We can set the $HISTTIMEFORMAT variable with a specific date and time format, the easiest option is to use %c as shown below.
echo 'export HISTTIMEFORMAT="%c "' >> ~/.bashrc
Once this user logs out and back in for the export to execute, the existing history file will show all contents as executing at the exact same time as the time information was not previously recorded. From here onward however, the date and time will be stored with each command in the bash history file.
[[email protected] ~]# history 5 39 Sun 28 Aug 2016 02:37:54 AM PDT firewall-cmd --add-service=http --permanent 40 Sun 28 Aug 2016 02:37:54 AM PDT firewall-cmd --reload 41 Sun 28 Aug 2016 02:37:54 AM PDT tailf /var/log/messages 42 Sun 28 Aug 2016 02:37:54 AM PDT restorecon -v /var/www/html/index.html 43 Sun 28 Aug 2016 02:49:27 AM PDT history 5
15. Change History File Location
By default the bash history is written to ~/.bash_history, this is set in the $HISTFILE variable as shown below.
[[email protected] ~]# echo $HISTFILE /root/.bash_history [[email protected] ~]# su - user [[email protected] ~]$ echo $HISTFILE /home/user/.bash_history
[[email protected] ~]# echo 'export HISTFILE="/root/new_history"' >> ~/.bashrc
16. Do Not Store Duplicate Commands
By default /etc/profile sets the $HISTCONTROL variable to ‘ignoredups’ which will ignore duplicate commands that are run one after the other. For example if we execute the ‘pwd’ command multiple times, it will only show once in the history.
[[email protected] ~]# pwd /root [[email protected] ~]# pwd /root [[email protected] ~]# pwd /root [[email protected] ~]# pwd /root [[email protected] ~]# history | grep pwd 1 Sun 28 Aug 2016 04:01:07 AM PDT pwd 2 Sun 28 Aug 2016 04:01:15 AM PDT history | grep pwd
17. Reverse Search
While we can browse previous commands with the techniques previously listed, my favourite is reverse search which is executed with ‘ctrl+r’. After pressing ‘ctrl+r’ you will see the the (reverse-i-search)`’: prompt, at this point you can start typing a command that has previously been executed and it will display the most recent command. You can cycle back further through previous commands that also contain this string by pressing ‘ctrl+r’ again and again until you find what you’re after.
(reverse-i-search)`httpd': systemctl start httpd
All history should also be taken with a grain of salt, as it is very easy to modify as by default a user has write permissions on their own ~/.bash_history file so they can modify it however they want, including deleting the contents to cover their tracks.
You could instead look at sending bash history to an external syslog server so that it cannot be modified, but that’s a story for another time.
Summary
As shown the history command is quite powerful, it allows us to view command history on a Linux system using Bash with a number of customizations available.
Share this:
How can I see all of the bash history?
In this case, the shell can not see the history executed by shell(1), but I want to see all of the bash history in every shell. So my question is how can I see all of the bash history? Does anybody know how to hack? Thank you very much in advance!
5 Answers 5
would also work, although I tend to just use
How to do it when I am working in a virtual environment (venv)? ~/.bash_history shows only the commands outside of the virtual environment.
@Raif — you would need access to the terminal within the virtual environment as the «user» running the app commands (root or the equivalent).
You should look into the histappend shell option and the -a flag to history :
histappend
If set, the history list is appended to the file named by the value of the HISTFILE variable when the shell exits, rather than overwriting the file.
history
-a Append the «new» history lines (history lines entered since the beginning of the current bash session) to the history file.
If you put history -a into your PROMPT_COMMAND , you’ll get an always-up-to-date .bash_history file.
Edit your .bashrc and append this to it’s end:
shopt -s histappend PROMPT_COMMAND="history -n; history -a" unset HISTFILESIZE HISTSIZE=2000
You can install something like Advanced Shell History, which will log each command to a sqlite3 database. It comes with a tool for querying the database from the command line. https://github.com/barabo/advanced-shell-history
With this setup, you will have a unified view of command history across all sessions. You also get things like command history for the current working directory (or subtree), command exit code, command duration, etc.
Full disclosure: I wrote and maintain the tool.
As several have noted, you need to use shopt -s histappend . Check by running shopt and verifying that histappend is ‘on’.
To ensure that each command (across multiple concurrent shells) appears in the history for each of those shells, add this at the end of your .bashrc file:
# Skip if not an interactive shell if [ -z "$" ]; then return; fi export PROMPT_COMMAND="history -a; history -c; history -r; $"
-a: appends the new history lines (history lines entered since the beginning of the current Bash session) to the history file.
-c: clears the history list.
-r: reads the current history file and append its contents to the history list.
Run source .bashrc or create new sessions and in several terminal windows enter the comment #Tn in each. Then on one terminal, enter history | tail -N to see the last N lines. You should see all of the comments entered on the different terminals.
It may be helpful to add the following to /etc/profile.d/bashrc.sh in order to get a timestamp on each line of the history:
if [ -z "$" ]; then return; fi export HISTTIMEFORMAT='%F %T '
The result looks like this:
[moi@laBoheme ~]$ history | tail -4 3292 2019-01-22 12:41:25 # T1 3293 2019-01-22 12:41:32 # T2 3294 2019-01-22 12:41:44 # T3 3295 2019-01-22 12:41:50 history | tail -4