Showing posts with label bash. Show all posts
Showing posts with label bash. Show all posts

Bash prompt customizations

Some paths can be really long and annoying. Here's how you fix it.
NOTE: I am using 14.04. Your mileage may vary.

Reduce the size of the prompt

This simple trick checks if the length of the current directory path is greater than 30. In that case, it breaks it up into two chunks -- first 12 letters and the last 15.

__update_prompt1()                                                                                                                                                                     
{                                                                                                                                                                                     
   DIR=`pwd | sed -e "s!$HOME!~!"`                                                                                                                                                   
   if [ ${#DIR} -gt 30 ]; then                                                                                                                                                       
     CurDir=${DIR:0:12}....${DIR:${#DIR}-15}                                                                                                                                       
   else                                                                                                                                                                              
     CurDir=$DIR                                                                                                                                                                   
   fi                                                                                                                                                                                
} 

Before:
[user@hostname:/local/mnt/workspace/somefolder1/foldera/test]$
After:
[user@hostname:/local/mnt/w....a/test/]$


Personally, I like the one below. It replaces the folder names with a single letter.


__update_prompt2()                                                                                                                                                                    
{                                                                                                                                                                                     
    CurDir=`pwd | sed -e "s!$HOME!~!" | sed -re "s!([^/])[^/]+/!\1/!g"`                                                                                                               
} 

Before:
[user@hostname:/local/mnt/workspace/somefolder1/foldera/test]$
After:
[user@hostname:/l/m/w/s/f/test]$

All we need to do is update the PROMPT_COMMAND and PS1


PROMPT_COMMAND=__update_prompt2                                                                                                                                                       
export PROMPT_COMMAND=${PROMPT_COMMAND}                                                                                                                                                                                                                           
PS1='[\u@\h:${CurDir}]\$ '                                                                                                                                     
export PS1 

There is one other thing I like to do -- move the cursor to the newline
PS1='[\u@\h:${CurDir}]\n\$ '

The prompt looks like,

[user@hostname:/l/m/w/s/f/test]
$ ls


Adding git branch information to prompt along with git completion


First things first, download the git-completion.bash and git-prompt.sh files from https://github.com/git/git/tree/master/contrib/completion

Add these do the .bashrc


source ~/.git-completion.bash
source ~/.git-prompt.sh 

And finally, update the PS1

PS1='[\u@\h:${CurDir}]$(__git_ps1 " (%s)")\n\$ '

When the folder is a git repository it will automatically show the current git branch.

[user@hostname:/l/m/w/s/f/myrepo] (master)
$ ls -a
. .. .git hello 

You get git completion for free as well.

[user@hostname:/l/m/w/s/f/myrepo] (master)
$ git che [TAB]
check-mailmap   checkout        cherry          cherry-pick


Preserving the history across terminals



This can be done in three simple steps
  1. history -a : Append the new history lines (history lines entered since the beginning of the current Bash session) to the history file
  2. history -c : Clear the history list. This may be combined with the other options to replace the history list completely
  3. history -r : Read the history file and append its contents to the history list

Let's do this part of the PROMPT_COMMAND

PROMPT_COMMAND=__update_prompt2
export PROMPT_COMMAND="history -a; history -c; history -r; ${PROMPT_COMMAND}"

That's it!

[Bash] Sending stdout and stderr to single file

Remember: To send both the stdout and stderr messages from the console to a file do:

$ app > log.file 2>&1

If you want to send everything to a black-hole just replace log.file with /dev/null.

$ app > /dev/null 2>&1

If ever confused about the syntax, do man bash and search for REDIRECTION for more gyan

Update:
It is good idea to use tee, which lets you see the output as well as write it to a file.

$ app 2>&1 | tee file.log

Control-S freezes puttty

Saw a weird behavior yesterday. CTRL-S would freeze putty. It turned out to be problem related to XOFF which is triggered by CTRL+S (the terminal will accept keys but it won't show the result for that, weird!). A simple fix is CTRL+Q to trigger XON. However, that does not work well with emacs which relies a lot on CTRL+S (for searching and saving)

Just add the following to .bashrc file:

stty ixany
stty ixoff -ixon

.thumbnails eating up space in $HOME

I have a restriction of 50K # of files that can be created in the $HOME folder at work and for no apparent reason I reached that limit a couple of days back. So, there was something that had created 50K files in $HOME and I did not know about it.

Ran the following:

$ for x in `find $HOME -name "[.]*"`; do echo "$x has `find $x | wc -l` file"; done

The result listed a folder $HOME/.thumbnails that had around 47776 files. It appears that Nautilus creates thumbnails of every picture or PDF that you have opened. However, Nautilus does not delete the files.

If you have such a restriction and need to get rid of these files, add a crob job that does deletes the files older than 7 days.

$ find ~/.thumbnails -type f -atime +7 -exec rm {} \;

Another method is to change the Gnome settings. Run the following:

$ gconf-editor

Under desktop -> gnome -> thumbnail_cache change the values for maximum_age and maximum_size

Print the IP of the machine at login

Wanted to know the IP address of the test machine the moment I log in. include the following in your .bashrc file.

echo "Welcome to" `hostname` "("`ifconfig eth0 | grep "inet addr:" | awk -F: '{print($2)}' | sed "s/ /:/g" | awk -F: '{print($1)}' `")"

Not very efficient use of sed and awk :(

Battery monitoring from console

If you prefer to work on a console based machine (without gdm\kdm), the following script is useful if you are running your laptop on battery. It shows the current battery charge and can be used for monitoring the battery discharge.

#!/bin/sh
# While working in console mode (without gdm) this script
# tells you the remaining charge of your laptop battery
#
# Run it along with watch on a separate tty
# $ watch -n 10 ./batmon
#
# (c) Hunterwala, 2009
#
# TODO: check for error levels and buzz using pcspkr mod
# when the charge level decreases beyond that level.

PROC_PATH="/proc/acpi/battery/BAT0"

org_cap=`cat $PROC_PATH/info | grep "last full capacity" | sed "s/ //g" | awk -F: '{print($2)}' | sed "s/mAh//g"`
rem_cap=`cat $PROC_PATH/state | grep "remaining capacity" | sed "s/ //g" | awk -F: '{print($2)}'| sed "s/mAh//g"`
message=`cat $PROC_PATH/state | grep "charging state" | sed "s/ //g" | awk -F: '{print($2)}'| sed "s/mAh//g"`

diff=$(echo "($org_cap-$rem_cap)" | bc)
total_per=$(echo "100-($diff*100/$org_cap)" | bc)

echo "Battery is" $message ":" $total_per"%"


Save this script as batmon.sh

Change the permissions chmod a+x batmon.sh

Run it on a separate tty watch -n 10 ./batmon.sh

sudo first

Check if you running your script through sudo.

if [[ $(/usr/bin/id -u) -ne 0 ]]; then
    echo "Not running as root"
    exit
fi

Bash scripting

1. A very good basic BASH scripting tutorial. Click here
2. A very advanced tutorial at TLDP. Click here

Changing the default size of gnome-terminal

The small window can be a pita sometimes.

Figure out what size you want to make the terminal. (If you have compiz enabled, while dragging the right bottom edge, you can get the size in the center of the screen, else trial-and-error)

Add gnome-terminal to the panel, change the properties and add the following to the command

gnome-terminal --geometry 152x55

(or whatever size you prefer)

[Book] Linux in a nutshell



This O'Reilly book is a good starter for people new to Linux. Here are the list of useful commands from the book.

[Image courtsey http://www.oreillynet.com]

Using cut and uniq

For some weird reason I had to do this, cut and uniq turned out to be quite handy and can be used along with sed

cat /proc/cpuinfo | grep "model name" | uniq | cut -d: -f2

So, instead of this
model name : Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz
model name : Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz


I get this
Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz

OK, another approach is to use awk
cat /proc/cpuinfo | grep "model name" | uniq | awk -F: '{print($2)}'

Using commands recursively with find

I copied my home folder to Windows for a backup and when I copied them back for some weird reason all the directories had executables privileges.

This is what I did to get rid of it recursively

$ find . -type d -exec chmod 755 {} \;

you can pass any command as an argument to -exec. Some useful things that you can do with find are here

working with core dump

Core dumps are very important when debugging a problem. But sometime you would notice that even after the program crashes with a Segmentation Fault, the size of the core dump file is still zero or in some cases the core dump is not created.

The size of the core dump file is governed by "ulimit" in bash. To get more information about ulimit, do a info on bash and search for ulimit

$info bash

To get the status of the current limits set you can do

ulimit -a

Notice the core file size (-c). If it reads 0, it means that bash would not create the core dump file. You need to change the size.

ulimit -c 1024

You can even set it to unlimited

ulimit -c unlimited


Generating the core

/* coredump.c */
#include <stdio.h>

int main (void)
{
  int *point = NULL;
  *point = 0;

  return 0;
}


Compile the code

gcc -g coredump.c -o coredump

When you try to run, it would generate a segmentation fault

./coredump
Segmentation fault (core dumped)


Using the core
To use the core, start gdb and pass the core dump generated

gdb coredump -c core
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.

Reading symbols...
Core was generated by ./coredump
Program terminated with signal 11, Segmentation fault.
#0 0x08048381 in main () at coredump.c:6
(gdb)


You can now use the gdb commands to view the call stack, registers, memory etc.

Performing an operation on multiple files using a single command line in bash

This is quite useful if you need to move files from multiple locations to a single place.

Let's assume that you have been searching for all *.jpg files on your system and you need to move all of them to a specific folder /home/deadpan/images,

To get the files do,

$ find . -name "*.jpg" . This would get you all the .jpg files.

To move all these files from various location to a single folder do,

$ for file in `find . -name "*.jpg"`; do mv $file /home/deadpan/images; done

By using regular expressions in find, as discussed here, you can get very specific in your search.