Educating yourself does not mean that you were stupid in the first place; it means that you are intelligent enough to know that there is plenty left to 'learn'. -Melanie Joy

Monday, 18 November 2013

Unix command line tricks

November 18, 2013 Posted by Dinesh , ,
1. Ever tried creating pdf files in your unix machine ??

man -t ascii | ps2pds - > ascii_man_page.pdf

-t flag formats the output and ps2pds converts post script to pdf.
hyphen (-) after ps2pdf command indicates it to read input from stdin and write output to stdout.


2. Want to terminate the script after first failure ?

'set -e' thats it. it does everything.

$> cat setexit.sh

#/bin/bash
set -e
echo "line 1"
cat tmp.x.12.12
echo "line 2"


$> ./setexit.sh
line 1
cat: tmp.x.12.12: No such file or directory #line 2 is not echoed


3. Simple way to create huge file

yes, we have 'yes' in unix to do that. yes will echo what ever you give as argument.

#press ctr+c after a while
$yes "some random text..." > bigfile.txt

'yes' has another interesting advantage. just imagine to answer yes to the every question by bash.

$rm file.txt
rm: remove regular file 'file.txt' ?

#you probably give 'y' to remove it. what if you want to remove 100 such files?

yes | rm *.sh
  

though this can be achieved just by ignoring alias ( \rm *.sh ) this is just an example to demonstrate the usage.


4. Creating dirty random number

we have $RANDOM shell variable to generate a random number may be max of 5 characters. If you wish to create a big random number use 'mcookie'. This command generates a "magic cookie," a 128-bit pseudorandom hexadecimal number, normally used as an authorization signature by the X server. This also available for use in a script as a quick and dirty random number.

$mcookie
a2cae14a060720bca183d05f165a5a8e


5. Get directory name or file name from path and file extension

#extract dir name and file name
$> basename /dir1/dir2/file.txt      
file.txt  
$> dirname  /dir1/dir2/file.txt 
/dir1/dir2

#Extract extension 
$> path="/dir1/dir2/file.txt"
$> ext=${path##*.}
$> echo $ext
txt


6. Simple 'cut'

var="one two three"
set -- $var
a=${1};   #one 
b=${2};   #two
c=${3};   #three

Just a basic example to avoid invoking forked process (cut/awk)


7. Base conversion

'bc' can convert from any base to any.

Ex: decimal to hexadecimal conversion
echo 'obase=16; ibase=10; 64' | bc            # (ibase=input base, obase=output base)

This will convert 64 from base 10 to base 16.



Friday, 1 November 2013

Programmable Completion : Autocomplete the arguments of your program

November 01, 2013 Posted by Dinesh ,
Auto completion is one of the best features in bash. How good if it completes argument for your program as well !!

The Bash complete and compgen builtins make it possible for tab completion to recognize partial parameters and options to commands. In a very simple case, we can use complete from the command-line to specify a short list of acceptable parameters.

with complete [option] [command] you define the completion for some command.

A basic example to illustrate auto completion:

lets think we have a script called 'run.sh' which will take 4 arguments --all, --help, --html, --version.
as you type run.sh -[TAB] it should display all the above four option.
to make it work lets write a small function will will be loaded by complete when ever TAB is pressed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# file: load_opt
_load_opt ()   
{                
  local cur
  COMPREPLY=()   
  cur=${COMP_WORDS[COMP_CWORD]}

  if [[ ${cur} == -* ]]
  then
    COMPREPLY=($(compgen -W "--all --help --html --version" -- $cur))
  return 0
  fi
}

complete -F _load_opt run.sh

save the file as load_opt.  and source it before running run.sh. then it shows the magic.

$  source load_opt

$  run.sh -[TAB][TAB]
--all --help --html --version

$ run.sh --h[TAB][TAB]
--help --html


How it works ?

Once the load_opt script is sourced, bash understands that run.sh arguments will be completed bye load_opt function which is specified by complete command at the end of load_opt file.
so when ever TAB is pressed  _load_opt function will be called.
This script has some special shell variables.

COMP_WORDS
An array variable consisting of the individual words in the current command line.
COMP_CWORD
An index into ${COMP_WORDS} of the word containing the current cursor position.
COMPREPLY
An array variable from which Bash reads the possible completions generated by a shell function invoked by the programmable completion facility
a local 'cur' variable is used to point current completion word.

so if your option starts with - it will match -* and set the value of COMPREPLY to the output of compgen [ check here ] command. compgen will return the matching words of 'cur'
and those set of words are assigned to COMPLREPLY array.
bash will now print those word to console.


But it is not a good idea of sourcing the loader before running the script.
so create this load_opt file under /etc/bash_completion.d/ directory. all the scripts which are under  /etc/bash_completion.d/ will be loaded by bash in the start up.
After adding the file under that directory you can run bash then run the script or you can source that file alone and run the script.


Note:
above example work if you run your script run.sh[TAB] not ./run.sh[TAB]. if you want it to work with ./ as well add 'complete -F _load_opt ./run.sh' also at the end of load_opt file.




compgen - List All Unix Commands !!

November 01, 2013 Posted by Dinesh , No comments

compgen is bash built-in command and it will show all available commands, aliases, and functions.
and it is used to get the specific set of words from a word list ( ?? )

To list all the commands available :

$ compgen -c
alert
c
d
egrep
fgrep
..
..
..
bzexe
espdiff
sol
gnome-mines
gnome-sudoku


To list all the bash shell aliases available :

$ compgen -a
alert
c
d
egrep
fgrep
grep
l
la


To list all the bash build-ins :

$ compgen -b
.
:
[
alias
bg
bind
break
builtin
caller
cd


To list all the bash keywords :

$ compgen -k
if
then
else
elif
fi
case
esac
for
select
while
until
do
done
in
function
time
{
}
!
[[
]]
coproc


To list all the bash functions :

dinesh@ubuntu:~$ compgen -A function
__colormgrcomp
__expand_tilde_by_ref
__get_cword_at_cursor_by_ref
__grub_dir
__grub_get_last_option
..
..
_zeitgeist_daemon
command_not_found_handle
dequote
quote
quote_readline

-A (action) is very useful option. The action may be one of the following to generate list of possible completions.
alias, arrayvar, binding, builtin, command, directory, enabled, disabled, export, file, function, group, hostname, job, keyword, running, service, setopt, signal, user, variable.


To get word[s] from word-list :


dinesh@ubuntu:$ compgen -W "aa ab ac ba bb"
aa
ab
ac
ba
bb
dinesh@ubuntu:$ compgen -W "aa ab ac ba bb" -- b
ba
bb
is it really useful ??