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

A useful little bashrc addition

I really like checking if commands have executed successfully. This is something quite important if you are administering a machine. Normally I just echo $? but now I have added a new line to my .bashrc that will show me this in colour.

export PS1='\[\033[0;32m\]\u@\h \[\033[0;33m\]\w\[\033[${?/[^0]/31}m\]\$ \[\033[0;38m\]'

This will make the prompt green if everything went OK and red if the process didn't return 0. Nice little helper :)

Think multi core!

Just another hacking tip.
I normally write little bash scripts that do repeating jobs for me and I wrote a little script (simplified):
for i in `seq 100`; do ./ogp.py $i ; done
Very simple you would say. But where is the problem with this? This only uses one CPU core at a time. I normally work on a 2 core machine but I will be buying a 8 core soon. So this script only uses one. So now my script looks like this:
for i in `seq 100`; do ./ogp.py $i & done
Can you spot the difference. Now I background the job (&) and the loop continues to run. I will not clog up the process ques as the program only runs
$time ./ogp.py 1

real 0m0.034s
user 0m0.025s
sys 0m0.008s

But it makes some difference. No backgrounding:
$ time ./gentest

real 0m2.206s
user 0m1.479s
sys 0m0.727s
And backgrounding
$ time ./gentest

real 0m1.128s
user 0m1.469s
sys 0m0.734s

So even with bash scripts you have to take the increase in core count serious.
Note: You don't need the line terminating ';' anymore as '&' acts as a line terminator too. So
for i in `seq 100`; do ./ogp.py $i &; done
Would be wrong

Add return codes to your shell prompt

How many times do you type 'echo $?' to check if the command you have just run really didn't silently exit with an error? When I do sys admin stuff I frequently do this. So now I just added the return code to my shell prompt. So if something goes wrong I see it right away. I have a FreeBSD box so this may vary from setup to setup.
export PS1='[\u@\h \w] $(echo $?) \$ '
the trick is the
$(echo $?)
I know this forks a new echo process every time you get a shell prompt. But the idea is that you enable this when you are doing important selected stuff. Possibly on a live system where you are not allowed to make any errors.

How to send a mail in bash

This is something very simple. How do you send a email in bash without having sendmail configured. Ok so I spent the whole afternoon writing this. It basically creates a file descriptor over a tcp socket and then sends data over it. Not really error robust, but it should do. I have to sleep all the time as I don't know when the server will respond. And I can't cat,tail or head the filedescriptor as I don't have a EOF. Anyway quite horrible hack, but maybe you can learn something from it. For example how smtp works :)

 1 #!/bin/bash
2 #
3 # A little script that sends out a mail purly in Bash :)
4 # Very very slow act
5 # {Jan.Michael,Geerd-Dietger.Hoffmann}@cern.ch
6 #
7
8 #set up some vars we need
9 nameofme=`uname -n`
10 ipofmail=`host cernmxlb.cern.ch | cut -d ' ' -f 4` #Have fun if dhcp goes down
11
12 #TODO : Something like if [ `ping -c 1 $ipofmail | wc -l` -eq 5];then echo "host down"; fi
13
14 #Create file pointer
15 exec 4<>/dev/tcp/$ipofmail/25
16 sleep 2
17 echo -en "EHLO $nameofme.cern.ch\r\n" >&4
18 sleep 5
19 echo -en "MAIL From:<you@root.ch> SIZE=770\r\n" >&4
20 sleep 2
21 echo -en "RCPT To:<you@root>\r\n" >&4
22 sleep 2
23 #And off we go
24 echo -en "DATA\r\n" >&4
25 sleep 1
26 echo -en "Nobody said computers were going to be polite.\r\n" >&4
27 sleep 1
28 echo -en ".\r\n" >&4
29 sleep 1
30 echo -en "QUIT\r\n" >&4
31
32 # Disable this if you don't wan't output
33 # Could be used for error checking something like this would be ok
34 # if [! `wc -l <&4` -eq 22];then echo "error in line count"; fi
35 sleep 1
36 cat <&4
37

Note: This of course will only work if you can reverse DNS and own the world