2011年8月3日 星期三

When did I installed this system?

0 意見
Sometimes I wondered when I installed the system.  For Red Hat-based systems, here is a simple one: query for the 'basesystem' package


# rpm -qi basesystem
Name        : basesystem                   Relocations: (not relocatable)
Version     : 8.0                               Vendor: Red Hat, Inc.
Release     : 4                             Build Date: Thu 23 Sep 2004 06:01:44 AM HKT
Install Date: Tue 01 Feb 2011 05:26:36 PM HKT    Build Host: tweety.build.redhat.com
Group       : System Environment/Base       Source RPM: basesystem-8.0-4.src.rpm
Size        : 0                                License: public domain
Signature   : DSA/SHA1, Thu 06 Jan 2005 07:03:37 AM HKT, Key ID 219180cddb42a60e
Packager    : Red Hat, Inc.
Summary     : The skeleton package which defines a simple Red Hat Linux system.
Description :
Basesystem defines the components of a basic Red Hat Linux system (for
example, the package installation order to use during bootstrapping).
Basesystem should be the first package installed on a system and it
should never be removed.

The answer can be seen on the line with 'Install Date: '.

More information:This package contains no files, only used for initial system installation and can't be removed from the system afterwards.

# rpm -ql basesystem
(contains no files)
2011年6月15日 星期三

1-line awk group sum calculaton

0 意見
I got a data text file with these lines

2011-02-05  apple   3
2011-02-05  orange  5
2011-02-10  apple   4
2011-02-25  pineapple  2
2011-03-05  apple   1
2011-04-11  orange  2
2011-04-16  pineapple  3

and I want to get the grouped sum quickly, like this:

apple 8
orange 7
pineapple 5

and I really don't want to import into a spreadsheet and do the manual filtering jobs.

Here is the 1-line shell-script solution using 'awk'

$ cat file.txt | awk '{ sum[$2]+=$3 } END { for (i in sum) { print i,sum[i]}} ' | sort

It works like magic :)
2010年2月12日 星期五

Read into read

0 意見
I encountered a case where I'm in the middle of a loop that read through a file through the 'read' command, like,

  while read a b c
  do
    .. (do something) ..
    # need user to input something
    read X
    .. (do some more things) ..
  done < file.txt

The 'read X' inside the loop will read data from the file 'file.txt' instead of console.

To solve the problem, simple change the 'read X' into
  read X < /dev/console
that forces the script reads the input from the terminal.

If you are connecting using SSH, replace /dev/console with your current console device.  You can see your current terminal device file by the environment variable $SSH_TTY (for OpenSSH) that usually is /dev/pts/0, /dev/pts/1 and so on.

Put a shell script function into background

0 意見
To run several shell script processes, but don't want the hassle of maintaining multiple scripts?  Yes, you can put them into functions within ONE script.  It's elegant, beautiful, and much easier to read and maintain.

Here is an example:
1  #!/bin/bash
2  #
3  # Test shell script with background function(s)
4  #
5
6  func1 ()
7  {
8    cat /dev/null > func1.txt
9    i=0
10   while [ $i -le 100 ];
11   do
12   echo $i >> func1.txt
13     echo "From func1: $i"
14   sleep 1
15   (( i = i + 1 ))
16 done
17 }
18
19 func2 ()
20 {
21   cat /dev/null > func2.txt
22   j=0
23   while [ $j -le 10 ];
24   do
25     echo $j >> func2.txt
26     echo "From func2: $j"
27   sleep 6
28   (( j = j + 1 ))
29   done
30 }
31
32 func1 &
33 x=$!
34 echo "func1 PID: $x"
35
36 func2 &
37 y=$!
38 echo "func2 PID: $y"
39
40 echo "Waiting for both function finishing..."
41 wait $y
42 wait $x
43
44 echo "Both function finishing, quit the main script."

As in shell prompt, we can add an '&' after the name of the calling functions (line 32,36), to put them into background.  In other words, the shell duplicates the original processes into several processes, as below:
debian-lenny:~# ps -ef | grep test
user      3517  3337  0 03:06 pts/0    00:00:00 /bin/bash ./test-bg.sh
user      3518  3517  0 03:06 pts/0    00:00:00 /bin/bash ./test-bg.sh
user      3521  3517  0 03:06 pts/0    00:00:00 /bin/bash ./test-bg.sh
Where 3517 is the parent process, and 3518 and 3521 are the duplicates.

In line 33 and 37, use the '$!' to get their Process IDs (PID), that are, 3518 and 3521 respectively.

Finally, use the 'wait' function (in line 41 and 42) for waiting them both finish, before printing the final message and exit.

This is quite useful in doing some tasks, like running multiple instances of file copy - that speeds things up.
 
My Unix Notes | © 2011 Design by DheTemplate.com and Theme 2 Blog

Find more free Blogger templates at DheTemplate.com - Daily Updates Free Blogger Templates