Category Archives: bash

Git branch name in command prompt


I normally work on multiple branches of a git repository and I tend to forget which branch I am currently in. If I don’t do ‘git branch‘, I sometimes make changes in the code and then realize that – Ah! this change should have been in a different branch. So I thought of adding a string to the command prompt which indicates which git branch I am in whenever I am in git repository branch directory. I Googled for this problem and got many solutions.

So currently I am using the following command prompt -

PS1="${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\[\033[01;37m\]\$(git branch 2>/dev/null | grep -e '\* ' | sed 's/^..\(.*\)/{\1}/')\[\033[00m\]\$ "

The git branch part is -

\$(git branch 2>/dev/null | grep -e '\* ' | sed 's/^..\(.*\)/{\1}/')

Explanation -

The command git branch 2>/dev/null | grep -e '\* ' | sed 's/^..\(.*\)/{\1}/' is executed every time you press enter on command prompt.

git branch – outputs all the branches with an asterisk on the current branch if you are in a git repository directory. Now the problem is if you are not in a git repository directory executing this command will give you an error. There is no side effect but you won’t like to see an error every time you press enter on command prompt.

To remove the error 2>/dev/null is added which redirects all error messages to /dev/null.

To get the current branch output of git branch is piped to grep -e '\* ' which outputs the string containing '* ' (asterisk followed by a white space). The current branch is indicated by '* ' (asterisk followed by white space) in the beginning of the string.

Now to remove the '* ' from the string to get the branch name output of grep is piped to sed 's/^..\(.*\)/{\1}/'. This command magically removes the first two characters of the string and surrounds the string with {}. To know how this magic happens refer to backreferences and remembering pattern and sed substitutions.

If you use a better command prompt to indicate git branch please comment to let me know.

Post Pidgin and Twitter status from command line


I often want to post the same status message in Pidgin and Twitter. I wrote  simple bash script to accomplish this.

One can download the script from here: http://www.spsneo.com/scripts/poststatus.tar.gz

How to use it -

1) Change the permission of the file to make it executable: chmod +x poststatus

2) Then execute the file with the status message as the argument: ./poststatus "Status Message goes here in quotes"

3) The script will first post the status message in your pidgin and will then ask whether you want to post it on twitter.  If you say yes, the script asks you for your twitter username and password.

Start using the script and send me feedback to improve it.

Bash History Tips and Tricks


Bash supports history expansion feature which can be very useful for powerful command-line users.

According to bash manual page -

History  expansions introduce words from the history list into the input stream, making it easy to repeat commands, insert the arguments to a previous command into the current input line, or fix errors in previous commands quickly.

History expansion is composed of three parts -

  • Event Designators: It is a reference to an entry in the history list.
  • Word Designators: It is used to select a word from the event.
  • Modifiers: Modifies the word selected by the word designator or the action of the command.

All the three parts are optional and are separated from each other by a : (colon). There can be multiple modifiers each separated by a : (colon).

Now I will explain each part one by one.

Event Designators:

  1. ! Start a history substitution, except when followed by a blank, newline, carriage return,  = or (
  2. !n It refers to n’th command in the history. So if you just type in
    !68 at the command prompt, 68th command in your history list will be executed.
  3. !-n It refers to n’th command in the history from last. So if you just type in !-1 at the command prompt, last command will be executed.
  4. !! is an alias for !-1. Example:
    $apt-get install gnome-ppp    //Permission Denied. You need to be sudo to do this!
    $sudo !!                      // This is equivalent to sudo apt-get install gnome-ppp
  5. !string It refers to the most recent command in the history starting with string. It is again an useful expansion when you don’t remember the arguments to a command which you have executed earlier.
  6. !?string[?] It refers to the most recent command containing string. The trailing ? may be omitted if string is immediately followed by a newline.

Word Designators:

  1. n The nth word, count starting from 0. 0th word normally refers to the command. Example:
    $sudo cat /etc/resolv.conf     //Instead you want to edit the resolv.conf file
    $sudo vi !!:2                       //This is equivalent to sudo vi /etc/resolv.conf
  2. ^ This refers to 1st word. This is equivalent to :1 as refered above. The only .advantage is that you can omit : (colon) when you use ^. Example:
    $cat ~/.bashrc
    $vi !!^        //This is equivalent to "vi !!:1" that is vi ~/.bashrc
  3. $ This refers to the last word.
  4. x-y This refers to a range of words; ‘-y‘ is equivalent to ’0-y’.
  5. * This refers to all the words except the 0th one. This is helpful when you have to execute a command with all the arguments passed to the last command.
  6. x* This is an alias for x-$ .

Note: If a word designator is used without an event specification, the last command in the history is used as the event. Example -
$cat ~/.bashrc
$vi !:1
// This is equivalent to vi !!:1 or vi ~/.bashrc

Modifiers:

  1. h This removes the trailing file name component, leaving the head. Example:
    $cat /home/spsneo/.bashrc
    $ls !!:1:h
    //This expands to ls /home/spsneoExplanation: !! refers to the last command and then :1 refers to the 1st word of the last command and then :h removes the trailing file name component i.e., .bashrc . Hence the expansion.
  2. t This removes all leading file name components, leaving the tail.
  3. r This removes the trailing suffix of the form .xxx , leaving the basename.
  4. p Print the new command but do not execute it.
  5. s/old/new This substitutes the first occurrence of old with new. Example:
    $cat /etc/resolv.conf
    $!!:s/resolv/yum
    //This expands to cat /etc/yum.conf
  6. g This is used in conjunction with “:s” modifier. This causes changes to be applied over the entire event line rather than just the first occurrence. Example:
    $cat test.cpp test.h
    $!!:gs/test/source/
    //This expands to cat source.cpp source.hh

This is all I have to share about bash history expansion.

Do post comments if you find any mistake or if you want any further clarifications. One can also go through the bash manual pages for more options.

Set BING Background as your Desktop Wallpaper in GNOME


BING comes up with a beautiful background everyday. I thought why not set this background as my desktop wallpaper. But it would be a cumbersome task to set it manually. So I searched (Googled, BINGed) for some script which will do this for me. I found BING Downloader which does this task on Windows. I could not find any such script for GNOME. So, I thought of writing one.

I wrote a script which when executed automatically sets the GNOME wallpaper as BING background of the day. This is a PHP script. To execute this script you need to have php installed on your system. You can install php in Ubuntu as

sudo apt-get install php5 php5-cli

Now you are all set to download this script. Download Link: http://www.spsneo.com/scripts/bing_wallpaper.tar.gz

Download this file, extract the script file. Now you can run the script from terminal :
php bing_wallpaper.php

And your wallpaper is set. You can run this script daily from your terminal or you can set a cron job for the same or you can set up an icon in your gnome panel for this script.

I will keep updating this script. And I am also planning to write the same script in python. So check back again if you dont want to install php on your system.

Send your feedbacks and suggestions.

Update 1: I have modified the script to work with http proxy. Just assure that the environment variable http_proxy is properly set.

Update 2: Modified the script to keep the image centered on the desktop with black background. Try it out.

Extract all Archive File Format With Just One Command in Linux


There are large number of archive file formats – .zip, .tar.gz, .tar, .gz, .7zip, .rar, etc etc..

I find it difficult to remember the command line options for extracting different archive file formats. So, I wrote a bash function which given a archive filename as an input extracts it.

Here’s the function :

extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xjf $1 ;;
*.tar.gz) tar xzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) rar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.tbz2) tar xjf $1 ;;
*.tgz) tar xzf $1 ;;
*.zip) unzip $1 ;;
*.z) uncompress $1 ;;
*) echo "'$1' cannot be extracted via extract ()" ;;
esac
else
echo "'$1' is not a valid file"
fi
}

This function is pretty self explanatory. But as it is not powerful. It becomes the ultimate tool for extractive archive files if you copy this function in you bashrc file (~/.bashrc).

Now you can simply extract any file like this:


$extract test.tar.gz

Hope you like this function.

Note: This function doesn’t work with files have space in its name. I didn’t waste time in solving this issue as I normally don’t use such filenames. If any of you solve this issue, please do let me know. I would include it with your name in this post. :D