Looping with For and While

[problem]

You want to loop a number of times in UNIX.

[/problem]

[solution]

Being able to loop around a given number of times, fully utilizes the power of UNIX. See the examples.

[/solution]

[example]

For example, spin around 100 times and print hello:

i=0; while [[ $i -lt 100 ]] ; do echo -n 'hello'; ((i++)) ; done; echo ''
hellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohello...

Similarily the for command is a beauty too, spin around 5 times and kick off a loop 5 times – paste the result into 5 columns:


for i in 1 2 3 4 5; do for j in 1 2 3 4 5; do echo "$i:$j"; done; done | paste - - - - -
1:1 1:2 1:3 1:4 1:5
2:1 2:2 2:3 2:4 2:5
3:1 3:2 3:3 3:4 3:5
4:1 4:2 4:3 4:4 4:5
5:1 5:2 5:3 5:4 5:5

[/example]

[reference]

[tags], Unix Coding School[/tags]

[/reference]

Check var for pattern

[problem]

You want to check a variable for a given pattern.

[/problem]

[solution]

This is my personal favorite way to check for values in vars. See examples.

[/solution]

[example]

[[ $(echo $var | grep -ic "pattern") -eq 0 ]] &

You could also go for “-eq 1” – does contain:

[[ $(echo $var | grep -ic "pattern") -eq 1 ]] &

Or “-ne 0” for same, etc.

[[ $(echo $var | grep -ic "pattern") -ne 0 ]] &

Plus you could use || for “or” either in place of “&&” or after this block – same as if .. then “positive” else “negative” fi.

[[ $(echo $var | grep -ic "pattern") -eq 0 ]] || { echo "var does contain pattern" }

[/example]

[reference]

[tags], Unix Coding School[/tags]

[/reference]

Detach proc from shell

[problem]

When you exit your shell, the processes you’ve kicked off die.

[/problem]

[solution]

If you start a process with nohop (ignore the hup signal), it will not exit (usually) when your shell is exited. nohup stands for no hang up, a throw back to terminal lines.

[/solution]

[example]

nohup command > /tmp/logfile.log 2>&1&

If you forget to run the command with nohup, this can now be simulated on solaris.

Just background the process (with ctrl Z and bg) then type disown.

disown [%1]

The UNIX command jobs will show all backgrounded jobs. After running disown, it should show no jobs in the background.

[/example]

[reference]

[tags]nohup, disown, daemons, Unix Coding School[/tags]

[/reference]

Binary Calculator Hex

[problem]

You want to perform some arithmetic with UNIX.

[/problem]

[solution]

The binary calculator, installed with pretty much all version of UNIX, can be used for an array of tasks.

Not just basic calculations, but also converting between bases and it can automated, etc.

[/solution]

[example]

It’s simpliest use, it just to run bc and add, subtract divide.


bc
888+999
1887

Be aware though, that to perform precision point calculations, you must specify the “-l” long option. For example:


bc
999/222
4

Obviously wrong! 🙂 Now with the long option:


bc -l
999/222
4.50000000000000000000

Can also be automated like this, to convert between decimal and hex:


i=0; while ((i < 20)) ; do echo -n ' $i: '; echo 'base=10;obase=16;$i' | bc; ((i++)); done | paste - - - -
0: 0 1: 1 2: 2 3: 3
4: 4 5: 5 6: 6 7: 7
8: 8 9: 9 10: A 11: B
12: C 13: D 14: E 15: F
16: 10 17: 11 18: 12 19: 13

[/example]

[reference]

[tags]BC, HEX, Unix Coding School[/tags]

[/reference]

VI Tips

[problem]

Started using vi probably 13 years ago and ever so often, still learn new tricks with it! 🙂

Some of my favorites are: turning on control characters; mapping function keys; performing global search and replace; remapping columns.

[/problem]

[solution]

So to the basics, editing a file:


vi filename

[/solution]

[example]

Editing a file from a specific line number or pattern:


vi +lineno filename
vi +/patt/ filename

To turn on control characters, once in vi – do the following (exactly)


:set list

To turn it off again:


:set nolist

Global replace:


:%s/patt/rep/g

Map function keys:


:map #1 :w![ctrl v ctrl m]

that is type colon,map,#,1,space,colon,w,!,^M then hit enter. More on this later.

Remap columns:


:%s/(col1patt) (col2patt)/2 1/

To finish here is a cool but slightly bizarre one:


:g/^/m0

It reverses the lines of file. Effectively it says – global (all lines) with this pattern (a beginning line – so all lines), move to 0 – which is shorthand for the current line. So as vi applies the command to each line, it bubbles up to the top.

[/example]

[reference]

[tags]vim, regular expression, Unix Coding School[/tags]

[/reference]

AJAX Gotcha Browser caching

[problem]

Spent many hours debug my code on elizaclaire.darlingranges.com.

I kept wondering why, whenever I updated the code – it did not get reflect through.

[/problem]

[solution]

Eventually but printing the date within the sub request, I found the browser was caching the sub request!

The fix was very easy, to force a header under apache – turning off caching.

[/solution]

[example]

Header set cache-control "no-cache"
Header set Pragma "no-cache"
Header set Expires "-1"

[/example]

[reference]

[tags][/tags]

[/reference]

AJAX And Javascript Functions Gotcha

[problem]

Spent many further hours debug my code on elizaclaire.darlingranges.com.

None of my javascript functions worked, in the resulting sub-request. Tried all sorts, even setting up an AJAX call, within the sub-request. Nothing worked.

[/problem]

[solution]

Eventually through masses of trial and error, “discovered” I had to define the javascript function, with the main body of the code.

In other words, within the subrequest made through AJAX you can have javascript triggers (onclick, onsubmit, onchange …) – but have them call functions previous define in your original web page.

[/solution]

[example]


------------------- demo.htm ------------------

....
function reset_cty() { .... }
...
var url="page_with_call_reset_cty.htm"
xmlhttp.open("GET",url, true)
-------------------------------------------------

----------- page_with_call_reset_cty.htm --------
...
... onclick = ... reset_cty ...

--------------------------------------------------

[/example]

[reference]

[tags][/tags]

[/reference]

AWK Find field number

[problem]

Ever needed to print out one column with awk, but do not know the field number?

[/problem]

[solution]

Here I’m running df and looking for a field with “Used” in it:

 df -k | head -1 | awk ' {       for(i=1; i< NF;i++) {          if($i ~ /Used/) {              print "# field "i          }       } } ' 

So stop counting columns and just use the code! 🙂

[/solution]

[example]

Now for a real life demo. 😉


[marcus@bree marcus]$ df -k | head -1
Filesystem 1K-blocks Used Available Use% Mounted on
[marcus@bree marcus]$ df -k | awk ' {
for(i=1;i < NF;i++) {
if($i ~ /Used/) { print "# field "i }
}
} '
# field 3

[/example]

[reference]

[tags], Unix Coding School[/tags]

[/reference]

AWK Print line number

[problem]

Ever wanted to display a line number, with each matching record from awk. Useful as a way of counting the number of matching lines too.

[/problem]

[solution]

Here’s how with a demo which grabs network stats (netstat) off my linux box. It looks for connections to port 80 and in TIME_WAIT state – prints a line number and the matching line.

[/solution]

[example]


[marcus@bree marcus]$ netstat -an -t | awk ' /:80 / && /TIME_WAIT/ { print ++i,$0} '
0 tcp 0 0 x.x.x.x:80 x.x.x.x:44154 TIME_WAIT

If you wanted the line number, that matches your pattern – this would show that too:


[marcus@bree marcus]$ netstat -an -t | awk ' /:80 / && /TIME_WAIT/ { print "line:"NR,"count:"++i,$0} '
line:17 count:1 tcp 0 0 x.x.x.x:4298 x.x.x.x:80 TIME_WAIT

[/example]

[reference]

[tags]gawk, netstat, print line numbers, Unix Coding School[/tags]

[/reference]

Send HTML email from command line

[problem]

Need to send an email from UNIX command line, that contains HTML content?

[/problem]

[solution]

Most useful when generating statistics, etc – just spin round and spit out HTML table rows, through sendmail.

[/solution]

[example]

Here is the code:


/usr/lib/sendmail -t
To:[email protected]
From:[email protected]
Subject:This is a test
MIME-VERSION:1.0
Content-Type: multipart/mixed; boundary="gc0y0pkb9ex"

--gc0y0pkb9ex
Content-type: text/html;charset="iso-8859-1"

<html><head><title>Test HTML mail</title></head>
<body>
<table border=1>
<tr><td align=center>test mail</td></tr>
<tr><td>This is an HTML email sent from UNIX command line!</td></tr>
</table>
</body></html>
.

[/example]

[reference]

[tags], Unix Coding School[/tags]

[/reference]