//Tips tagged history
Latest tips by RSS
Click here to subscribe
Follow Shell-Fu on Twitter
Click here to follow
Follow Shell-Fu on identi.ca
Click here to follow
Running a second command with the same arguments as the previous command, use '!*' to repeat all arguments or '!:2' to use the second argument. '!$' uses the final argument.
$ cd /home/user/foo
cd: /home/user/foo: No such file or directory
$ mkdir !*
mkdir /home/user/foo
Don't search history by grepping ~/.bash_history, or repeatedly hitting the up arrow, instead use CTRL+r (or '/' in vi-mode) for search-as-you type. You can immediately run the command by pressing Enter.
Forget that your running as underprivileged? No need to retype the command.
> command_with_insufficient_permissions
Permission denied
> sudo !!
> command_with_insufficient_permissions
Permission denied
> sudo !!
Often I find myself using Ctrl-R in Bash to get an old command, only to find that too many days have passed and it's no longer in the .bash_history file.
It is possible to increase the number of lines in the history file, but there can always be a moment when you'll need a long command from many months ago. The solution below uses the PROMPT_COMMAND variable, a command that bash executes before showing each prompt. Here are the two lines to add to your profile:
If a previous PROMPT_COMMAND was set, it gets executed before this and then appends a line of the format:
PID USER INDEX TIMESTAMP COMMAND
to a file called .bash_permanent_history in the current user home.
Adding the username is useful to distinguish between "sudo -s" sessions and normal sessions which retain the same value for "~/", and so append lines to the same .bash_permanent_history file.
It is possible to increase the number of lines in the history file, but there can always be a moment when you'll need a long command from many months ago. The solution below uses the PROMPT_COMMAND variable, a command that bash executes before showing each prompt. Here are the two lines to add to your profile:
export HISTTIMEFORMAT="%s "
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ; }"'echo $$ $USER \ "$(history 1)" >> ~/.bash_permanent_history'
If a previous PROMPT_COMMAND was set, it gets executed before this and then appends a line of the format:
PID USER INDEX TIMESTAMP COMMAND
to a file called .bash_permanent_history in the current user home.
Adding the username is useful to distinguish between "sudo -s" sessions and normal sessions which retain the same value for "~/", and so append lines to the same .bash_permanent_history file.
If, like me, you often make mistakes on the command line, try using the history shortcut '^^' to repeat the last command with changes.
For example:
For example:
$ cat fiel cat: fiel: No such file or directory $ ^el^le cat file
Instead of adding a prefix to the previous command with 'Up-arrow Home prefix Space' try 'prefix !!' to repeat the last command with 'prefix ' before it.
You can also use '!-n' to use commands other than the most recent.
You can also use '!-n' to use commands other than the most recent.
Use the following to see the commands you use most often based on your shell history:
history | awk '{print $2}' | sort | uniq -c | sort -rn | headAdd the following to your ~/.inputrc to make the up and down keys search your history (using what you have typed in already as a prefix) rather than just go through all history items:
"\e[A": history-search-backward
"\e[B": history-search-forward
"\e[A": history-search-backward
"\e[B": history-search-forward
When I read the tip yesterday (Twitter from the terminal), I thought it would be fun to set something up to tweet all the commands I enter. After a bit of playing around I have come up with the following:
First you'll need to create a script, it doesn't matter what you call it, just remember the name and path to it for later.
You'll need to replace YOURUSER and YOURPASS as appropriate, and if you prefer to use identi.ca then change the twitter url to https://identi.ca/api/statuses/update.xml
Next run the following command, changing details at the end for the script you just created (note this does require you to use bash):
Now every command you type will be sent to twitter! To turn this off, just run "export PROMPT_COMMAND=''" or logoff. Of course this isn't really a good idea to do all the time, though it is fun! Also remember that Twitter will block accounts that post over 100 updates per hour.
An example of the results can be seen here: https://twitter.com/ShellStream
First you'll need to create a script, it doesn't matter what you call it, just remember the name and path to it for later.
#!/bin/bash
read MSG
echo $MSG > characters
length=$(wc -c characters | sed 's/^[^0-9]*\([0-9]*\)[^0-9]*$/\1/')
if [ $length -le 140 ]; then
wget -q --keep-session-cookies --http-user=YOURUSER --http-password=YOURPASS \
--post-data="status=$MSG" \
https://twitter.com/statuses/update.xml;
fi
You'll need to replace YOURUSER and YOURPASS as appropriate, and if you prefer to use identi.ca then change the twitter url to https://identi.ca/api/statuses/update.xml
Next run the following command, changing details at the end for the script you just created (note this does require you to use bash):
export PROMPT_COMMAND='echo "$(history 1)" | sed "s/^ *[0-9]* *//" | /path/to/script.sh'
Now every command you type will be sent to twitter! To turn this off, just run "export PROMPT_COMMAND=''" or logoff. Of course this isn't really a good idea to do all the time, though it is fun! Also remember that Twitter will block accounts that post over 100 updates per hour.
An example of the results can be seen here: https://twitter.com/ShellStream
Typically when one types the history command, it displays the command number and the command. For auditing purposes it would be helpful to display the timestamp as well. To do so we need to set the environmental variable HISTTIMEFORMAT.
HISTTIMEFORMAT supports format strings of strftime.
Some important format strings:
%T Replaced by the time ( %H : %M : %S )
%F Equivalent to %Y - %m - %d
Now execute
it will print the command line history with corresponding timestamp when the command was executed, such as:
HISTTIMEFORMAT supports format strings of strftime.
Some important format strings:
%T Replaced by the time ( %H : %M : %S )
%F Equivalent to %Y - %m - %d
$ export HISTTIMEFORMAT='%F %T '
Now execute
$ history
it will print the command line history with corresponding timestamp when the command was executed, such as:
499 2009-02-11 18:20:52 ls
Disable history for a particular account in bash with:
(in home dir)
(in home dir)
rm .bash_history
ln -sf /dev/null .bash_history
Use the following command to give a history listing without the numbers for easier copy and pasting:
history | sed 's/^[ 0-9]* //'

