You’re not a machine. At least, not most of the time. Like any human, you might be fooled by your imperfection and commit what we call a human error.
The ensuing three short tips will help bring some peace of mind when you are not-so-sure about your guiltiness, or just let you know that you need to assume your error and think of a way to repair the damage.
Add a timestamp to your bash history
This small tip will allow you to look forward in your shell history, knowing when each of your commands was executed:
~$ export HISTTIMEFORMAT="%d/%m/%y %T "
~$ history
1 05/05/16 18:07:03 clear
2 05/05/16 18:07:04 cd
3 05/05/16 18:07:05 ls -ltr
4 05/05/16 18:07:07 clear
5 05/05/16 18:07:12 touch file
6 05/05/16 18:07:17 chmod +rw file
7 05/05/16 18:07:22 chmod +x file
8 05/05/16 18:07:28 cat > file
9 05/05/16 18:07:34 git commit -a -m ‘cool feature'
10 05/05/16 18:07:36 git push
If you want to make this permanent, add the following line to your .bashrc
file.
export HISTTIMEFORMAT="%d/%m/%y %T "
Share your immediate bash history across multiple sessions
Nowadays, almost everyone uses more than one window or tab at the same time. Browser tabs, chats windows, and of course multiple console sessions. As you might have already noticed, your bash history is saved to the disk at the end of the session when you log out. This is perfectly fine most of the time, but for several reasons you might want to share that command history immediately with your other sessions.
To do that, you can just add this to your .bashrc
file.
export HISTCONTROL=ignoredups:erasedups
shopt -s histappend
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Now, let me explain how it works:
- The first statement will avoid duplicate entries in your command history.
- The second statement appends the history to your history file, instead of rewriting it.
- The third statement will set the
PROMPT_COMMAND
variable with the commands that will save the file, cleanup the in-memory command history stack, and reload the file from the disk again. The PROMPT_COMMAND
variable contents are executed every time you execute a command in the shell session, or when you just press Enter, and then when the history stack is updated in the current session.
Check which files were modified by a command
There is an overall safety rule when working with the command line: if you don’t know what it does, don’t run it. However, sometimes you want to execute particular things, even your code in your test environment, to “see what happens”.
Well, take that mysterious command and run it like this:
D="$(date "+%F %T.%N")"; sleep 0.5; <command>; find . -newermt "$D"
Where <command>
is what you want to execute.
This example takes the current time and saves its value to the variable D
, then waits for a half second and executes the command. Finally, search for any new file created since that moment in the current directory. It’s not perfect, as another process might have modified the files during that period, but it will give you an excellent idea about which files you need to inspect and look for changes.
There are a few notes about the sleep
command. Besides the fact that the date
command is taking the time in nanoseconds resolution, your machine might be fast, and some of the files might not be caught by find
. It’s always better to inspect false-positive results than miss some real occurrences. This time, I’m assuming that you’re using GNU sleep
, which currently supports resolutions under 1 second. Otherwise, just use 1
keeping in mind that by extending the time to be evaluated by find, you might see some additional false-positive results.
Now, check this example:
# D="$(date "+%F %T.%N")"; sleep 0.5; ./mysterious ; find /etc -newermt "$D";
Dont't worry, I'm good
/etc/passwd
The mysterious
command, despite the fact it prints “Don’t worry, I’m good”, modified your /etc/passwd
file and you just found it by executing it in this way.