Pages

Wednesday, 16 January 2013

OpenCMS (Java CMS)

သာမန္သံုးေနက် PHP CMS ေတြထက္ security ပိုင္းမွာပိုသာပါလိမ့္မယ္။ OpenCMS ဟာ Java Application ၿဖစ္တဲ့အတြက္ Apache Tomcat, JBoss, BEA WebLogic, IBM Websphere စတဲ့ Java Application server ေတြနဲ ့ run လို ့ရပါတယ္။ Database အေနနဲ ့လည္း common ၿဖစ္တဲ့ Oracle, Sybase ASE, MySQL တို ့နဲ ့ compact ၿဖစ္ပါတယ္။ ဒီ tutorial မွာေတာ့ MySQL ရယ္ Tomcat ရယ္ နဲ ့ဘဲ သံုးထားပါတယ္။  ပထမဦးဆံုး MySQL ကို install လုပ္ပါမယ္။ အေသးစိတ္ installation ကိုေတာ့ ေနာက္ မွဘဲ MySQL Installation on Solaris 10 ဆိုတဲ့ post မွဘဲေရးပါ့မယ္။  MySQL install လုပ္ၿပီးရင္ set global max_allowed_packet=3354432; ဆိုၿပီး maximum allow packet ကို ေၿပာင္းေပးပါ။ (/etc/my.cnf ထဲမွာေၿပာင္းၿပီး mysql ကို restart လုပ္ေပးလဲရပါတယ္) OpenCMS က maximum allow packet 16MB  အနဲဆံုးလိုပါတယ္။


 ၿပီးရင္ tomcat ကို download လုပ္ၿပီး extract လုပ္ပါ။ openCMS ကို http://www.opencms.org/en/download/opencms.html ကေန download လုပ္ပါ။ ၿပီးရင္ tomcat extract လုပ္ထားတဲ့ path ကို CATALINA_HOME ဆိုၿပီး variable assign လုပ္ပါ။ JDK ကိုလည္း JAVA_HOME ဆိုၿပီး variable assign လုပ္ပါ။ (Solaris 10 မွာေတာ့ က်ေနာ္ default JDK နဲ ့ဘဲသံုးထားပါတယ္။)

OpenCMS ကို extract လုပ္ၿပီးရင္ opencms.war ကို CATALINA_HOME/webapps ရဲ ့ေအာက္ကို extract လုပ္ေပးပါ။ ၿပီးရင္ tomcat ကိုစလို ့ရပါၿပီ။ CATALINA_HOME/bin/startup.sh ကို စေပးလိုက္ရင္ရပါၿပီ။



 ၿပီးရင္ tomcat host ရဲ ့IP နဲ ့browser ကေန access လုပ္ၿပီး WebUI ကေန setup လုပ္ရင္ရပါၿပီ။
http://192.168.56.5:8080/opencms/setup/




ၿပီးရင္ database information ေတြထည့္ေပးပါမယ္။ (ကြ်န္ေတာ္ကေတာ့ root access မေပးဘဲ သီးသန္ ့အေကာင့္တခုဖြင့္ schema တခု create လုပ္ၿပီး grant access လုပ္ေပးထားပါတယ္။)





 ၿပီးရင္ Continue ဆက္လုပ္ပါမယ္။





Continue နဲ ့ဆက္သြားၿပီးရင္ေတာ့ opencms ရဲ ့ modules ေတြ ကို import လုပ္ပါလိမ့္မယ္။


Import process ၿပီးသြားပါၿပီ။
http://192.168.56.5:8080/opencms/opencms ကေနၿပီး access လုပ္လို ့ရပါၿပီ။




Administration အတြက္ http://192.168.56.5:8080/opencms/opencms/system/login ကေန access လုပ္လို ့ရပါတယ္။




(URL context ကို  / ရဖို ့အတြက္ reverse proxy သံုးမွဘဲအဆင္ေၿပပါလိမ့္မယ္။)

Tomcat port setting ေတြ၊ reverse proxy သံုးမယ္ ဆိုရင္ proxy settings ေတြကို configure လုပ္ဖို ့ကေတာ့ CATALINA_HOME/conf/server.xml ထဲမွာေၿပာင္းနိုင္ပါတယ္။
(Reverse Proxy Server အေနနဲ ့ Oracle iPlanet ဒါမွမဟုတ္ nginx တို ့apache တို ့ကိုလည္း သံုးနိုင္ပါတယ္။)

tomcat server.xml file ထဲက Connector tag example ပါ။

<Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"

                proxyPort="80"/>

SSL ကေတာ့ ကိုယ္သံုးမယ့္ reverse proxy ေပၚမွာပဲ run နိုင္ပါတယ္။


Saturday, 15 December 2012

Perl Script အေၿခခံ

Unix/Linux Admin ေတြအေနနဲ ့Shell Script တစ္ခုတည္းနဲ ့မလံုေလာက္ပါဘူး။ တခ်ိဳ ့Automation Script ေတြမွာ Perl, Python,  Awk အစရိွသၿဖင့္ တၿခား Programming Language ေတြ ေရာၿပီးအသံုးၿပဳရတာမ်ိဳးေတြရိွပါတယ္။ အခုေအာက္မွာ နမူနာေပးထားတာ ကေတာ့ က်ေနာ္ေရးထားတဲ့ Perl Script တခုၿဖစ္ပါတယ္။ အကုန္လံုးကို Perl command ေတြခ်ည္း သံုးထားတာ မဟုတ္ဘဲ Shell command ေတြကိုပါ ေရာသံုးထားပါတယ္။ scp process တို ့ unzip လုပ္တဲ့ေနရာတို ့မွာပါ။ unzip တို ့scp တို ့ကို Perl command ေတြခ်ည္းသံုးခ်င္ရင္ သက္ဆိုင္ရာ Perl Module ေတြ install လုပ္ရမွာၿဖစ္လို ့ အခုလိုမ်ိဳး shell command ေတြကိုသံုးထားတာပါ။

အခု script ကေတာ့ java web application တခုကို svn server ကေန copy ကူးၿပီး deploy လုပ္တဲ့ script ၿဖစ္ပါတယ္။ Deploy လုပ္မယ့္ file ေပၚမူတည္ၿပီး statement ေတြကို ထပ္ထည့္သြားလို ့ရတယ္။ 
ေအာက္က ဖိုင္မွာေတာ့ Deploy လုပ္မယ့္ file တခုတည္းအေနနဲ ့ၿပထားတယ္။


1:  #!/usr/bin/perl  
2:  # Deployment Script --WH (UPDATED 14NOV2012)  
3:  # Define the Directory Path below.  
4:  use File::Path;  
5:  $target = "/opt/weblogic/tmp";  
6:  $host = 'root@svn-host-ip:';  
7:  $checkout = "/opt/checkout/";  
8:  $today = `date '+%Y%m%d'`;  
9:  $appdir = "/opt/weblogic/deploy/ROOT";  
10: sub process_scp();  
11: sub extract_file();  
12: sub menu();  
13: sub do_exit();  
14: system ('clear');  
15: menu ();  
16: sub menu() {  
17: print <<"MENU";  
18: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
19:    Deploy script $today  
20:           1.Web Application Deploy  
21:           2.Exit  
22:    Choose which number you want to deploy  
23: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
24: MENU  
25: $number = <>;  
26: chomp ($number);  
27: if ($number eq "1") {  
28:      unlink(<$target/ROOT*>);  
29:      &process_scp("ROOT*");  
30:      extract_file();  
31:  } elsif ($number eq "2") {  
32:       do_exit();  
33:  } else {  
34:      menu();  
35:      print "Please enter the valid input\n";  
36:  }  
37:  }  
38:  sub process_scp() {  
39:  system ('scp ' . "$host" . "$checkout" . "@_" . " $target");  
40:  print "Copied @_ to $target\n";  
41:  }  
42:  sub extract_file() {  
43:  for ($number) {  
44:  if (($number) eq "1") {  
45:  print "Deploying Web Application\n";  
46:  rmtree([$appdir]);  
47:  mkdir $appdir;  
48:  system ('unzip' . " $target/ROOT* " . ' -d ' . $appdir);  
49:  print "Web Application Deployed!\n";  
50:  menu();  
51:  } else {  
52:  print "invalid input!\n";  
53:  menu();  
54:  }  
55:  }  
56:  }  
57:  sub do_exit(){  
58:  print "Exiting...\n";  
59:  return;  
60:  } 


Line နံပါတ္ ၁ ကေတာ့ perl နဲ ့run မယ့္ script ဆိုၿပီးေၿပာထားတာပါ။
Line နံပါတ္ ၂ နဲ ့ ၃ ကေတာ့ comment ပါ။
Line နံပါတ္ ၄ က File::Path ဆိုတဲ့ Module ကိုသံုးမယ္ဆိုၿပီး ေၿပာထားတာပါ။
Line နံပါတ္ ၅ ကေန ၉ အထိက variables ေတြ ေၾကၿငာထားတာပါ။
Line နံပါတ္ ၁၀ ကေန ၁၃ အထိက sub routines ေတြေၾကၿငာထားတာပါ။
Line နံပါတ္ ၁၄ ကေတာ့ system command ၿဖစ္ၿပီး screen ေပၚက cache ေတြကို clear လုပ္မွာၿဖစ္ပါတယ္။
Line နံပါတ္ ၁၅ ကေတာ့ menu ဆိုတဲ့ sub routine ကို သံုးမယ္လို ့ေၿပာထားတာပါ။
Line နံပါတ္ ၁၆ ကေန ၃၇ ထိက menu ဆိုတဲ့ sub routine.
Line နံပါတ္ ၁၇ ကေန ၂၄ ထိက  MENU ကို print ထုတ္တာပါ။
Line နံပါတ္ ၂၅ က User ရိုက္ထည့္မယ့္ နံပါတ္ကို $number ဆိုတဲ့ variable အၿဖစ္သတ္မွတ္ေပးတာပါ။
Line နံပါတ္ ၂၆ ကေတာ့ လက္ခံထားတဲ့ input ကေန newline character ေတြကိုဖယ္ထုတ္ေပးတာပါ။
Line နံပါတ္ ၂၇ ကေန ၃၆ ထိကေတာ့ if else statement ပါ။
input က 1 ၿဖစ္ခဲ့ရင္ line နံပါတ္ ၂၈ ၊ ၂၉ ၊ ၃၀ တို ့ကို execute လုပ္ပါမယ္။
Line နံပါတ္ ၂၈ ကေတာ့ ဖိုင္ဖ်က္တာပါ။ copy လုပ္မဲ့ destination မွာ version အေဟာင္းနဲ ့ဖိုင္ရိွခဲ့ရင္ ၾကိဳဖ်က္ထားတာပါ။
extract လုပ္ရင္ wildcard name နဲ ့လုပ္မွာၿဖစ္လို ့ ဖိုင္ ၂ ဖိုင္ၿဖစ္ေနရင္ error ၿဖစ္သြားနို္င္လို ့ပါ။
Line နံပါတ္ ၂၉ ကေတာ့ process_scp ဆိုတဲ့ sub routine ကို ROOT* ဆိုတဲ့ wildcard file name argument နဲ ့ execute လုပ္မွာပါ။
Line နံပါတ္ ၃၀ ကေတာ့ extract_file ဆိုတဲ့ sub routine ကို execute လုပ္မွာပါ။
Line နံပါတ္ ၃၁ မွာေတာ့ အကယ္၍ input က 2 ၿဖစ္ခဲ့ရင္ Line နံပါတ္ ၃၂ မွာေရးထားတဲ့ အတိုင္း do_exit ဆိုတဲ့ sub routine ကို execute လုပ္မွာပါ။
Line နံပါတ္ ၃၃ မွာေတာ့ အကယ္၍ input က 1 သို ့မဟုတ္ 2 မဟုတ္ဘူး ဆိုရင္ Line နံပါတ္ ၃၄ မွာေရးထားတဲ့အတိုင္း menu ဆိုတဲ့ sub routine ကို ၿပန္ေခၚမွာပါ။ (Looping ၿဖစ္သြားတဲ့သေဘာပါ။)
ၿပီးရင္ Line နံပါတ္ ၃၅ မွာၿပထားတဲ့အတိုင္း Please Enter the valid input ဆိုၿပီး print ထုတ္ေပးမွာပါ။
Line နံပါတ္ ၃၈ ကေန ၄၁ အထိကေတာ့ process_scp ဆိုတဲ့ sub routine ၿဖစ္ပါတယ္။
Line နံပါတ္ ၃၉ ကေတာ့ shell command ၿဖစ္ၿပီး scp location-of-source-file destination-folder ဆိုတဲ့ command context ကို သက္ဆိုင္ရာ variables value ေတြနဲ ့အစားထိုးၿပီး execute လုပ္မွာပါ။
Line နံပါတ္ ၄၂ ကေန ၅၆ အထိကေတာ့ extract_file ဆိုတဲ့ sub routine ၿဖစ္ပါတယ္။
Line နံပါတ္ ၄၃ ကေတာ့ menu မွာတုန္းက key-in လုပ္ခဲ့တဲ့ $number ဆိုတဲ့ variable ကိုၿပန္ေခၚထားတာၿဖစ္ပါတယ္။
Line နံပါတ္ ၄၄ ကေတာ့ အကယ္၍ $number ရဲ ့value ဟာ 1 ၿဖစ္ခဲ့ရင္ Line နံပါတ္ ၄၅ ကေန ၅၀ အထိကို execute လုပ္သြားမွာပါ။
Line နံပါတ္ ၄၅ ကေတာ့ Deploying Web Application ဆိုတဲ့စာသားကို print ထုတ္ေပးမွာၿဖစ္ပါတယ္။
Line နံပါတ္ ၄၆ ကေတာ့  $appdir ဆိုတဲ့ Web Application's deployed folder နဲ ့ ေအာက္မွာရိွတဲ့ contents ေတြကို ဖ်က္ေပးမွာၿဖစ္ပါတယ္။
Line နံပါတ္ ၄၇ ကေတာ့ $appdir ကိုၿပန္ create လုပ္မွာၿဖစ္ပါတယ္။
Line နံပါတ္ ၄၈ ကေတာ့ ခုနက scp နဲ ့ကူးထားခဲ့တဲ့ application.war file ကို $appdir ထဲကို extract လုပ္ေပးမွာၿဖစ္ပါတယ္။
Line နံပါတ္ ၄၉ ကေတာ့ Web Application Deployed ဆိုတဲ့စာသား ကို print လုပ္မွာၿဖစ္ပါတယ္။
Line နံပါတ္ ၅၀ ကေတာ့ menu ဆိုတဲ့ subroutine ကိုၿပန္ေခၚသံုးထားတာပါ။
Line နံပါတ္ ၅၁ ကေတာ့ အကယ္၍ ရဲ ့value က 1 မဟုတ္ခဲ့ရင္ Line နံပါတ္ ၅၂ ကေန Invalid input ဆိုၿပီး print ထုတ္မွာၿဖစ္ၿပီး
Line နံပါတ္ ၅၃ ကေန sub routine menu ကိုၿပန္ေခၚေပးမွာၿဖစ္ပါတယ္။
Line နံပါတ္ ၅၇ ကေန ၆၀ ကေတာ့ do_exit ဆိုတဲ့ sub routine ၿဖစ္ၿပီး Line နံပါတ္ ၅၈ ကေန Exiting ဆိုၿပီး print ထုတ္မွာၿဖစ္ပါတယ္။ ၿပီးရင္ Line နံပါတ္ ၅၉ က return command နဲ ့program ကို quit လုပ္ေပးမွာပါ။

Wednesday, 12 December 2012

Shell Scripts မ်ား

Shell Scripts ေတြအေၾကာင္း ရွင္းရရင္ေတာ့ တပံုၾကီးပါ။ ကိုယ္တိုင္စာအုပ္ဖတ္ၾကည့္မွ ပဲေတာ္ေတာ္ မ်ားမ်ား အေၾကာင္းကို တီးမိေခါက္မိ ရိွနိုင္ပါ့မယ္။ အခုဒီမွာနမူနာၿပထားတာကေတာ့ Java Process တခုရဲ ့Performance ကို jstat , jmap , နဲ ့ jstack ဆိုတဲ့ Java command ၃ခုကို သံုးၿပီး Monitor လုပ္ရာမွ ရလာတဲ့ result ကို mail နဲ ့ၿပန္ ပို ့ေပးမွာပါ။ Java process ေတြရဲ ့PID ကို သိေအာင္လုပ္တဲ့ေနရာမွာ unix command (ဥပမာ ps -ef လိုမ်ိဳး) ကိုအသံုးမၿပဳဘဲ jps ဆိုတဲ့ Java command ကိုသံုးထားပါတယ္။


ဒီေနရာမွာ အဓိကေၿပာခ်င္တာက script ရဲ ့အလုပ္လုပ္ ပံုသာၿဖစ္ၿပီး Java အေၾကာင္း မဟုတ္ပါ။
က်ေနာ္ကိုယ္တိုင္လည္း Java ကြ်မ္းက်င္သူတေယာက္မဟုတ္ပါ။ ဒီ နမူနာေပးထားတဲ့ script ကေတာ့ က်ေနာ္ ကိုယ္တိုင္ေရးထားတာ ၿဖစ္လို ့ဘယ္သူမဆို အသံုးတည့္မည္ဆိုရင္ လိုအပ္သလို ၿပန္ၿပင္ၿပီးသံုးနိုင္ပါတယ္။

script နွစ္ခုကို ေရးထားၿပီး တခုကေန တခုကိုေခၚသံုးတဲ့ပံုစံပါ။ တစ္ကယ္ေတာ့ JVM တခုထဲကို လုပ္မယ္ဆိုရင္ ဒီတခုထဲနဲ ့တင္ရပါတယ္။ JVM ၂ ခု ဒါမွမဟုတ္ ၂ ခုထက္ပိုခဲ့မယ္ဆိုရင္ အခုၿပထားတဲ့ example ထဲကလိုသံုးမွ အဆင္ေၿပနိူင္မွာပါ။ အခုၿပထားတဲ့ ဥပမာမွာ jvmlog.sh နဲ ့vm.sh တို ့ကို folder တခုေအာက္မွာထားၿပီး jvmlog.sh ကို execute လုပ္လိုက္တာနဲ ့vm.sh ကို ေခၚသံုးသြားမွာပါ။

ေအာက္က script ကို jvmlog.sh ဆိုၿပီး နာမည္ေပးထားပါတယ္။

 #!/bin/sh  
 JDK_32=/usr/jdk/instances/jdk1.6.0/bin  
 echo "Logging JVM for Jgroup ..."  
 /opt/jvmlog/vm.sh `${JDK_32}/jps | grep -v Jps | awk {'if($2=="GossipRouter") print $1, $2 '}`  


#!/bin/sh ဆိုတာ shell နဲ ့run မည့္ဖိုင္ဆိုၿပီး ညြန္းထားတာၿဖစ္ပါတယ္။

JDK_32=/usr/jdk/instances/jdk1.6.0/bin ဆိုတာ JDK Path ကို ေၾကၿငာထားတဲ့ variable ၿဖစ္ပါတယ္။

echo ဆိုတာကေတာ့ shell ရဲ ့print ထုတ္တဲ့ command ၿဖစ္ၿပီး ေနာက္က " " ထဲမွာရိွတဲ့စာသားကို print ထုတ္ေပးမွာၿဖစ္ပါတယ္။

/opt/jvmlog/vm.sh ဆိုတဲ့ script ကိုသြား run ေပးမွာပါ။ ေနာက္က `` ထဲက value က output ၂ခု ထုတ္ေပးမွာၿဖစ္ၿပီး အဲဒီ output ကို vm.sh ဆိုတဲ့ script ထဲမွာ အသံုးၿပဳမွာပါ။

${JDK_32}/jps commandကို run လိုက္ရင္ ရိွသမွ် Java process ေတြရဲ ့PID နဲ ့class name ေတြ ထြက္လာမွာပါ။

grep -v Jps ဆိုတာက အခု run လိုက္တဲ့ jps ရဲ ့process ကို output ထဲကေန remove လုပ္လိုက္တာပါ။

awk {'if($2=="GossipRouter") print $1, $2 '} ကေတာ့ GossipRouter ဆိုတဲ့ Class name ရိွတဲ့ process ရဲ ့PID နဲ ့class name ကို output ၂ ခုအေနနဲ ့ထုတ္တာပါ။ ဒီေနရာမွာ awk ကိုမသံုးဘဲ တၿခား shell command  ေတြ (ဥပမာ cut , sed လိုမ်ိဳး) ေတြကိုသံုးလည္းရပါတယ္။



ေအာက္က script ကို vm.sh ဆိုၿပီး နာမည္ေပးထားပါတယ္။  

 #!/bin/sh  
 SERVER=10.65.0.84  
 JDK_32="/usr/jdk/instances/jdk1.6.0/bin"  
 ROOTDIR="/opt/jvmlog"  
 DATE=`date "+%Y-%m-%d-%H:%M"`  
 RECP="myname@mydomain.com"  
 SNDR="myname@mydomain.com"  
 mkdir -p $ROOTDIR/logs/$2  
 LOGDIR=$ROOTDIR/logs/$2  
 JMAPEND=$LOGDIR/"jmap_"$DATE".log"  
 JSTACKEND=$LOGDIR/"jstack_"$DATE".log"  
 JSTATEND=$LOGDIR/"jstate_"$DATE".log"  
 WORKFILE=/tmp/fxspacelog.txt  
 ${JDK_32}/jmap -histo:live $1 > $JMAPEND  
 echo "Jmap Log for $2 $DATE on ${SERVER}" > ${WORKFILE}  
 echo >> ${WORKFILE}  
 cat $JMAPEND >> ${WORKFILE}  
 sleep 2  
 ${JDK_32}/jstack -l $1 > $JSTACKEND  
 echo >> ${WORKFILE}  
 echo "Jstack Log for $2 $DATE on ${SERVER}" >> ${WORKFILE}  
 echo >> ${WORKFILE}  
 cat $JSTACKEND >> ${WORKFILE}  
 sleep 2  
 ${JDK_32}/jstat -gcutil -t -h20 $1 1000 20 >> $JSTATEND  
 echo >> ${WORKFILE}  
 echo "Jstat Log for $2 $DATE on ${SERVER}" >> ${WORKFILE}  
 echo >> ${WORKFILE}  
 cat $JSTATEND >> ${WORKFILE}  
 mailx -r ${SNDR} -s "Java Log for $2 $DATE on ${SERVER}" ${RECP} < ${WORKFILE}  


#!/bin/sh ဆိုတာ shell နဲ ့run မည့္ဖိုင္ဆိုၿပီး ညြန္းထားတာၿဖစ္ပါတယ္။
SERVER ကေနၿပီး WORKFILE ဆိုတဲ့အထိက variables မ်ားေၾကၿငာထားတာၿဖစ္ပါတယ္။ 
ဒီ script ကို run ရင္ေနာက္ကေန input နွစ္ခုထည့္ေပးရမွာၿဖစ္ပါတယ္။ ပထမ input ($1) ကေတာ့ JVM ရဲ ့PID ၿဖစ္ၿပီး။ ဒုတိယ input ($2) ကေတာ့ သူ ့ရဲ ့class name ၿဖစ္ပါတယ္။

${JDK_32}/jmap -histo:live $1 > $JMAPEND
${JDK_32}/jmap ဆိုတာက jmap command ကိုေခၚတာၿဖစ္ၿပီး၊ -histo:live ဆိုတာကသူ ့ရဲ ့switch ပါ။ $1 ကေတာ့ PID number ၿဖစ္ၿပီး၊ > sign ကေတာ့ output ကို $JMAPEND ဆိုတဲ့ဖို္င္ထဲကို redirect လုပ္သြားဖို ့ပါ။

echo "Jmap Log for $2 $DATE on ${SERVER}" > ${WORKFILE}
သက္ဆိုင္ရာ variable ေတြရဲ ့value နဲ ့ စာေၾကာင္း ကို ${WORKFILE} ထဲကို write ပါလိမ့္မယ္။

echo >> ${WORKFILE}
blank လိုင္း တခုကို print ထုတ္ၿပီး ${WORKFILE} ထဲကို append လုပ္လိုက္တာပါ။

cat $JMAPEND >> ${WORKFILE}
$JMAPEND ထဲက log ေတြကို ${WORKFILE} ထဲကို append လုပ္လိုက္တာပါ။

sleep 2
၂ စကၠန္ ့ေလာက္ ခဏနားေနတာပါ။

ၿပီးရင္ jstat နဲ ့jmap လည္းသူတို ့သက္ဆိုင္ရာ command ေတြ switch ေတြသံုးၿပီး အလုပ္လုပ္ပါလိမ့္မယ္။ အားလံုးၿပီးသြားရင္ရိွသမွ် log ေတြက ${WORKFILE} ထဲမွာ ေရးထားၿပီးသားၿဖစ္ေနပါလိမ့္မယ္။

mailx ကေတာ့ e-mail ပို ့တဲ့ shell command ၿဖစ္ပါတယ္။ သက္ဆိုင္ရာ variable ေတြရဲ ့value ေတြကိုသံုးၿပီး ပို ့သြားမွာၿဖစ္ပါတယ္။ Message Body အေနနဲ ့ ${WORKFILE} ကိုအသံုးၿပဳမွာၿဖစ္ပါတယ္။


Friday, 17 August 2012

Runlevel Scripts သို ့မဟုတ္ StartUp Scripts မ်ား

Solaris 10 မွာ အခု Default Runlevel သံုးထားတာက runlevel 3 ၿဖစ္တဲ့အတြက္ Startup ဖိုင္ ေတြကို /etc/rc3.d/ ေအာက္မွာထားေပးရပါမယ္။ Script ေတြကို Linux မွာလိုပဲ S အၾကီး နဲ ့စေပးၿပီး ဂဏန္းနဲ ့တြဲေပးထားပါတယ္။ ဥပမာ S98.mysql တို ့S99.openfire တို ့လိုမ်ိဳးပါ။  File name ကိုေတာ့ကိုယ့္စိတ္ၾကိဳက္ေပးထားလို ့ရပါတယ္၊ သတိၿပဳရမွာကေတာ့ S အၾကီးနဲ ့စၿပီး ဂဏန္းနဲ ့တြဲထားဖို ့ပါ။  ေနာက္ ကဂဏန္းေတြေပၚမူတည္ၿပီး OS က အစဥ္လိုက္ Execute လုပ္သြားမွာၿဖစ္ပါတယ္။ အခုပံုစံမွာဆို ရင္ MySQL ကို အရင္စၿပီး ေတာ့မွ Openfire ကိုစမွာၿဖစ္ပါတယ္။ 98 ကို အရင္စၿပီးမွ 99 ကိုစတယ္ဆိုတဲ့သေဘာပါ။

ဒီဟာကေတာ့ S99.openfire နမူနာပါ။

 #!/bin/sh  
 RUNIN=/opt/openfire  
 RUNAS=openfire  
 case "$1" in  
 'start')  
     echo "Starting OpenFire server..."  
     su $RUNAS -c 'cd $RUNIN && ./start-openfire.sh'  
         ;;  
 'stop')  
     echo "Stoping OpenFire server..."  
     su $RUNAS -c 'cd $RUNIN && ./stop-openfire.sh'  
         ;;  
 *)  
     echo "Usage: $0 { start | stop }"  
     exit 1  
        ;;  
        esac  
        exit 0  

တလိုင္းခ်င္း ၿပန္ရွင္းၿပရမယ္ဆိုရင္ #!/bin/sh ဆိုတာ Bourne Shell နဲ ့ဒီ Script ကို Execute လုပ္မယ္လို ့ေၿပာတာပါ။ ဒီေနရာမွာ Bash Shell နဲ ့လုပ္ခ်င္တယ္ဆိုရင္ #!/bin/bash လို ့ေၿပာင္းေပးလိုက္ရင္ရပါတယ္။

RUNIN=/opt/openfire ဆိုတာက RUNIN ဆိုတဲ့ variable ကိုေၾကၿငာတာပါ။ သူ ့ရဲ ့value က /opt/openfire ပါ။

RUNAS=openfire ဆိုတာက လည္း RUNAS ဆိုတဲ့ variable ကိုေၾကၿငာတာၿဖစ္ၿပီး သူ ့ရဲ ့့value ကေတာ့ openfire ဆိုတာၿဖစ္ပါတယ္။

case "$1" in ဆိုတာကေတာ့ ဒီေနရာမွာ $1 ရဲ ့value ကို ထည့္ၿပီးစဥ္းစားမွာၿဖစ္ပါတယ္။

'start') ဆိုတာ $1 ရဲ ့value ဟာ start ၿဖစ္ခဲ့ရင္ ဒီေနရာကေနစၿပီး ;; ဆိုတဲ့ေနရာအထိကို execute လုပ္မွာၿဖစ္ပါတယ္။

su $RUNAS -c  ဆိုတာ user ေၿပာင္းပါမယ္။ ဒီေနရာမွာ RUNAS ရဲ ့value က openfire ဆိုတဲ့အတြက္ openfire ဆိုတဲ့ user ေၿပာင္းၿပီး ေနာက္က ' xxxxx' ထဲမွာရိွတဲ့ command ကို execute ဆက္လုပ္ပါလိမ့္မယ္။ 'cd $RUNIN && ./start-openfire.sh' ဆိုေတာ့ RUNIN ရဲ ့value ၿဖစ္တဲ့  /opt/openfire ထဲကို ၀င္ၿပီး start-openfire.sh ဆို တဲ့ script ကို execute လုပ္မွာၿဖစ္ပါတယ္။
အားလံုးၿခံဳၿပီးေၿပာရမယ္ဆိုရင္ေတာ့ openfire ကို root အေနနဲ ့မ run ခ်င္လို ့openfire ဆိုတဲ့ user ကိုေၿပာင္းၿပီး run လိုက္တာပါပဲ။

ဒီလိုဆိုရင္ stop case ကိုလည္းသေဘာေပါက္မွာပါ။ ဒီအတိုင္းပါပဲ။ start-openfire.sh ေနရာမွာ stop-openfire.sh ဆိုတာေလးပဲေၿပာင္းသြားတာပါ။

*) ကေတာ့ $1 ေနရာမွာ start သို ့မဟုတ္ stop မဟုတ္ဘူးဆိုရင္ ဒီ case ထဲကို၀င္သြားပါၿပီ။ အဲဒီအခါက်ရင္ေတာ့ Usage ဟာ start သို ့မဟုတ္ stop နဲ ့တြဲသံုးရပါမယ္ ဆိုၿပီး print ထုတ္ေပးပါလိမ့္မယ္။


ဒီ script ကအေၿခခံ ေလးတစ္ခုပါပဲ။ ကိုယ္လိုခ်င္တဲ့ပံုစံကို case ေပါင္းစံုနဲ ့ေရးလို ့ရပါတယ္။


reboot သို ့မဟုတ္ halt command ေတြလုပ္တိုင္းဒီ script ကို execute လုပ္သြားမွာၿဖစ္ပါတယ္။ shutdown ဒါမွမဟုတ္ init command ေတြနဲ ့ သံုးတဲ့အခါမွာ အဆင္ေၿပဖို ့အတြက္ဆိုရင္ ေတာ့ /etc/rc0.d/ ေအာက္မွာ ဒီ script ကိုပဲ K99.openfire ဆိုတဲ့နာမည္နဲ ့ထားေပးရပါမယ္။

မ်ားေသာအားၿဖင့္ေတာ့ ဒီ script ေတြကို သူ ့ရဲ ့ Parent Directory ေအာက္မွာပဲထားေလ့ရိွၿပီး /etc/rc3.d/ တို ့ /etc/rc0.d/ တို ့ေအာက္ကို symbolic link အေနနဲ ့ပဲထားၾကပါတယ္။ ဒါမွ တခုခု ေၿပာင္းခ်င္တဲ့အခါ တိုင္း centralize ၿဖစ္ၿပီးအဆင္ေၿပမွာပါ။

Thursday, 16 August 2012

Solaris Disk Mirror ၿပဳလုပ္ၿခင္း

အရင္ Solaris version ေတြၿဖစ္တဲ့ 8 တို ့ 9 တို ့မွာေတာ့ DiskSuite ကိုသီးသန္ ့တင္ေပးရတယ္။ Solaris 10 မွာေတာ့က်ေနာ္ Entire Distribution ကို Install လုပ္ထားတဲ့အတြက္ DiskSuite တင္စရာမလို ေတာ့ဘူး။ အခုဒီက်ဴတိုရီရယ္ ကိုလုပ္ဖို ့အတြက္ ခုနက Solaris 10 တင္ထားတဲ့ Virtual Machine ကို Shutdown လုပ္ လိုက္ၿပီး HDD ေနာက္တလံုး ထပ္ထည့္လိုက္ပါမယ္။ HDD ဆိုဒ္ခ်င္းေတာ့တူရမယ္။

မူလရိွေနတာက Disk 1 ေပါ့။ အခုထပ္ထည့္လိုက္တာက Disk 2 ပါ။ OS ေပၚမွာေတာ့ အခုလိုမ်ိဳး c0t0d0 နဲ ့ c0t1d0 ဆိုၿပီး ေပၚပါလိမ့္မယ္။
Disk 1   : c0t0d0
Disk 2   : c0t1d0

ေအာက္ကပံုေလးကို ေသခ်ာၾကည့္လိုက္ရင္ Disk Mirroring ဘယ္လိုအလုပ္လုပ္တယ္ဆိုတဲ့ concept ကို သေဘာေပါက္ပါလိမ့္မယ္။ Physical Disk က c0t0d0 နဲ ့ c0t1d0 ပါ။ Physical Disk ေတြကို Logical Name ေတြ Assign လုပ္ၿပီး၊ Logical Disk ေတြအခ်င္းခ်င္း ခ်ိတ္ဆက္ေပးလိုက္တဲ့သေဘာပါ။


Primary Disk ရဲ ့Slice 0 ၿဖစ္တဲ့ c0t0d0s0 ကို d10 ဆိုၿပီး  logical name တခု assign လုပ္ပါတယ္။ Secondary Disk ရဲ ့Slice 0 ၿဖစ္တဲ့ c0t1d0s0 ကို d20 ဆိုၿပီး  logical name တခု assign လုပ္ပါတယ္။
ၿပီးမွ d0 ဆိုတဲ့ logical drive ကို d10 နဲ ့d20 တို ့နဲ ့ ခ်ိတ္ဆက္ေပးပါတယ္။ ့့
OS ရဲ ့vfstab ထဲမွာ လက္ရိွ အသံုးၿပဳေနတဲ့ c0t0d0s0 အစား d0 ကို  သံုးမယ္ဆိုၿပီး ေၿပာင္းေပးလိုက္ပါတယ္။

ပထမဆံုး OS boot တက္လာၿပီဆိုရင္ devfsadm ဆိုတဲ့ command ကို ရိုက္ေပးလိုက္ပါ။ Device အသစ္ေတြကို Loading လုပ္ေအာင္လို ့ပါ။ ၿပီးရင္ format ဆိုတဲ့ command ကိုသံုးၿပီး Secondary Disk ကို Primary Disk နဲ ့တူေအာင္ Partition ေတြပိုင္းေပးပါမယ္။

 # format  
 Searching for disks...done  
 AVAILABLE DISK SELECTIONS:  
     0. c0t0d0 <DEFAULT cyl 2607 alt 2 hd 255 sec 63>  
      /pci@0,0/pci8086,2829@d/disk@0,0  
     1. c0t1d0 <DEFAULT cyl 2608 alt 2 hd 255 sec 63>  
      /pci@0,0/pci8086,2829@d/disk@2,0  
 Specify disk (enter its number):  

1 ကိုေရြးေပးလိုက္ပါ။

 Specify disk (enter its number): 1  
 selecting c0t2d0  
 [disk formatted]  
 FORMAT MENU:  
     disk    - select a disk  
     type    - select (define) a disk type  
     partition - select (define) a partition table  
     current  - describe the current disk  
     format   - format and analyze the disk  
     fdisk   - run the fdisk program  
     repair   - repair a defective sector  
     label   - write label to the disk  
     analyze  - surface analysis  
     defect   - defect list management  
     backup   - search for backup labels  
     verify   - read and display labels  
     save    - save new disk/partition definitions  
     inquiry  - show vendor, product and revision  
     volname  - set 8-character volume name  
     !<cmd>   - execute <cmd>, then return  
     quit  
 format>  

fdisk လို ့ရိုက္ေပးလိုက္ပါ။

 format> fdisk  
 No fdisk table exists. The default partition for the disk is:  
  a 100% "SOLARIS System" partition  
 Type "y" to accept the default partition, otherwise type "n" to edit the  
  partition table.  
 y  
 format>  

partition လို ့ရိုက္ေပးပါ။

 format> partition  
 PARTITION MENU:  
     0   - change `0' partition  
     1   - change `1' partition  
     2   - change `2' partition  
     3   - change `3' partition  
     4   - change `4' partition  
     5   - change `5' partition  
     6   - change `6' partition  
     7   - change `7' partition  
     select - select a predefined table  
     modify - modify a predefined partition table  
     name  - name the current table  
     print - display the current table  
     label - write partition map and label to the disk  
     !<cmd> - execute <cmd>, then return  
     quit  
 partition>  

ၿပီးရင္ Slice 0, 1,3 နဲ ့7 တို ့ကို Disk 1 မွာရိွတဲ့ အတိုင္း Partition ပိုင္းေပးပါ။ ဒီေနရာမွာသတိထားရမွာ ဆလင္ဒါ နံပါတ္ ကိုမွန္ေအာင္ ေပးဖို ့ပါ။ Slice တခုပိုင္းၿပီးတိုင္း ဆံုးတဲ့နံပါတ္ကို print ထုတ္ၿပီးၾကည့္လို ့ရပါတယ္။


 partition> 0  
 Part   Tag  Flag   Cylinders    Size      Blocks  
  0 unassigned  wm    0        0     (0/0/0)      0  
 Enter partition id tag[unassigned]:  
 Enter partition permission flags[wm]:  
 Enter new starting cyl[0]:  1 ########NOTICE#########
 Enter partition size[0b, 0c, 0e, 0.00mb, 0.00gb]: 7004mb  
 partition> 1  
 Part   Tag  Flag   Cylinders    Size      Blocks  
  1 unassigned  wm    0        0     (0/0/0)      0  
 Enter partition id tag[unassigned]:  
 Enter partition permission flags[wm]:  
 Enter new starting cyl[0]: 894 ##########NOTICE#######
 Enter partition size[0b, 0c, 0e, 0.00mb, 0.00gb]: 2000mb  
 partition> 3  
 Part   Tag  Flag   Cylinders    Size      Blocks  
  3 unassigned  wm    0        0     (0/0/0)      0  
 Enter partition id tag[unassigned]:  
 Enter partition permission flags[wm]:  
 Enter new starting cyl[0]: 1149 ##########NOTICE####### 
 Enter partition size[0b, 0c, 0e, 0.00mb, 0.00gb]: 101mb  
 partition> 7  
 Part   Tag  Flag   Cylinders    Size      Blocks  
  7 unassigned  wm    0        0     (0/0/0)      0  
 Enter partition id tag[unassigned]:  
 Enter partition permission flags[wm]:  
 Enter new starting cyl[0]: 1162 ##########NOTICE####### 
 Enter partition size[0b, 0c, 0e, 0.00mb, 0.00gb]: 11334mb  
 partition>  

ၿပီးရင္ print ထုတ္ၿပီးစစ္ၾကည့္ပါ။ အဆင္ေၿပၿပီဆိုရင္ label ဆိုၿပီး ရိုက္ေပးလိုက္ပါ။

 partition> print   
 Current partition table (unnamed):   
 Total disk cylinders available: 2607 + 2 (reserved cylinders)   
 Part   Tag  Flag   Cylinders    Size      Blocks  
  0    root  wm    1 - 893    6.84GB  (893/0/0) 14346045  
  1    swap  wu   894 - 1148    1.95GB  (255/0/0)  4096575  
  2   backup  wm    0 - 2606    19.97GB  (2607/0/0) 41881455  
  3 unassigned  wm  1149 - 1161   101.98MB  (13/0/0)   208845  
  4 unassigned  wm    0        0     (0/0/0)      0  
  5 unassigned  wm    0        0     (0/0/0)      0  
  6 unassigned  wm    0        0     (0/0/0)      0  
  7 unassigned  wm  1162 - 2606    11.07GB  (1445/0/0) 23213925  
  8    boot  wu    0 -  0    7.84MB  (1/0/0)    16065  
  9 unassigned  wm    0        0     (0/0/0)      0  
 partition> label    
 Ready to label disk, continue? y    
 partition> quit   


Slice 3 ေပၚမွာ State Database Replica ကို လုပ္ပါမယ္။ ေအာက္ပါ အတိုင္းလုပ္ပါ။


metadb –a  -c3 –f /dev/dsk/c0t0d0s3
metadb –a  -c3 –f /dev/dsk/c0t1d0s3

ၿပီးရင္ Primary Disk မွာရိွတဲ့ Slice ေတြအတြက္ Logical Disk ေတြကို လုပ္ပါမယ္။ ေအာက္ပါ အတိုင္းလုပ္ပါ။

metainit -f d10 1 1 c0t0d0s0
metainit -f d11 1 1 c0t0d0s1
metainit -f d13 1 1 c0t0d0s1
metainit -f d17 1 1 c0t0d0s7

ၿပီးရင္ Secondary Disk ကိုလည္း ေအာက္ပါ အတိုင္းလုပ္ေပးပါ။

   metainit -f d20 1 1 c0t1d0s0
   metainit -f d21 1 1 c0t1d0s1
   metainit -f d23 1 1 c0t1d0s1
   metainit -f d27 1 1 c0t1d0s7

Primary Disk ကို Mirror ခ်ိတ္ေပးပါမယ္။
    
   metainit d0 -m d10
   metainit d1 -m d11
   metainit d3 -m d13
   metainit d7 -m d17


Mirror ခ်ိတ္ၿပီးၿပီဆို ရင္ / partition အတြက္ metaroot command ကို run ေပးပါ။ ဒီ command run လိုက္မွ /etc/system ေအာက္ကတခ်ိဳ ့parameters ေတြနဲ ့/etc/vfstab ဖိုင္ထဲမွာ path ကိုခ်ိန္းပါမယ္။
ဒီ command မလုပ္ေပးရခင္ reboot လုပ္လိုက္မယ္ဆို OS က boot မတက္ေတာ့ပါဘူး။ အေရးၾကီးပါတယ္။

   metaroot d0

ၿပီးရင္ /etc/vfstab ကို ေၿပာင္းေပးပါမယ္။ ေအာက္ပါနမူနာအတုိင္းေၿပာင္းေပးလိုက္ပါ။ မူလ /dev/dsk/c#t#d#s# နဲ ့/dev/rdsk/c#t#d#s# ကေနၿပီး /dev/md/dsk/d#  နဲ ့ /dev/md/rdsk/d# ဆိုၿပီးေၿပာင္းေပးလိုက္တာပါ။



 #device     device     mount      FS   fsck  mount  mount  
 #to mount    to fsck     point      type  pass  at boot options  
 #  
 fd   -    /dev/fd fd   -    no   -  
 /proc  -    /proc  proc  -    no   -  
 /dev/md/dsk/d1 -    -    swap  -    no   -  
 /dev/md/dsk/d0 /dev/md/rdsk/d0 /    ufs   1    no   -  
 /dev/md/dsk/d7 /dev/md/rdsk/d7 /opt  ufs   2    yes   -  
 /devices    -    /devices    devfs  -    no   -  
 sharefs -    /etc/dfs/sharetab    sharefs -    no   -  
 ctfs  -    /system/contract    ctfs  -    no   -  
 objfs  -    /system/object objfs  -    no   -  
 swap  -    /tmp  tmpfs  -    yes   -  



ၿပီးရင္ reboot လုပ္လိုက္ပါ။ ၿပန္တက္လာၿပီဆိုရင္ Secondary Disk နဲ ့Mirror ခ်ိတ္ေပးပါမယ္။
 
metattach d0 d20
metattach d1 d21
metattach d3 d23
metattach d7 d27 


ခ်ိတ္ၿပီးသြားၿပီဆိုရင္ေတာ့သူ ့ဘာသာသူ Synchronize လုပ္ပါလိမ့္မယ္။ Monitor လုပ္ခ်င္ရင္ေတာ့ metastat ကိုသံုးၿပီးလုပ္လို ့ရပါတယ္။ Resyncing ဆိုၿပီးေတြ ့ရမွာပါ။


 # metastat  
 d7: Mirror  
   Submirror 0: d17  
    State: Okay  
   Submirror 1: d27  
    State: Resyncing  
   Resync in progress: 9 % done  
   Pass: 1  
   Read option: roundrobin (default)  
   Write option: parallel (default)  
   Size: 23213925 blocks (11 GB)  
 d17: Submirror of d7  
   State: Okay  
   Size: 23213925 blocks (11 GB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t0d0s7     0   No      Okay  Yes  
 d27: Submirror of d7  
   State: Resyncing  
   Size: 23213925 blocks (11 GB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t1d0s7     0   No      Okay  Yes  
 d3: Mirror  
   Submirror 0: d13  
    State: Okay  
   Submirror 1: d23  
    State: Okay  
   Pass: 1  
   Read option: roundrobin (default)  
   Write option: parallel (default)  
   Size: 192780 blocks (94 MB)  
 d13: Submirror of d3  
   State: Okay  
   Size: 192780 blocks (94 MB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t0d0s3   16065   Yes      Okay  Yes  
 d23: Submirror of d3  
   State: Okay  
   Size: 192780 blocks (94 MB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t1d0s3   16065   Yes      Okay  Yes  
 d1: Mirror  
   Submirror 0: d11  
    State: Okay  
   Submirror 1: d21  
    State: Okay  
   Pass: 1  
   Read option: roundrobin (default)  
   Write option: parallel (default)  
   Size: 4096575 blocks (2.0 GB)  
 d11: Submirror of d1  
   State: Okay  
   Size: 4096575 blocks (2.0 GB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t0d0s1     0   No      Okay  Yes  
 d21: Submirror of d1  
   State: Okay  
   Size: 4096575 blocks (2.0 GB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t1d0s1     0   No      Okay  Yes  
 d0: Mirror  
   Submirror 0: d10  
    State: Okay  
   Submirror 1: d20  
    State: Resyncing  
   Resync in progress: 7 % done  
   Pass: 1  
   Read option: roundrobin (default)  
   Write option: parallel (default)  
   Size: 14346045 blocks (6.8 GB)  
 d10: Submirror of d0  
   State: Okay  
   Size: 14346045 blocks (6.8 GB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t0d0s0     0   No      Okay  Yes  
 d20: Submirror of d0  
   State: Resyncing  
   Size: 14346045 blocks (6.8 GB)  
   Stripe 0:  
     Device   Start Block Dbase    State Reloc Hot Spare  
     c0t1d0s0     0   No      Okay  Yes  
 Device Relocation Information:  
 Device  Reloc Device ID  
 c0t1d0  Yes  id1,sd@SATA_____VBOX_HARDDISK____VBcb5e6d6b-901bd4d2  
 c0t0d0  Yes  id1,sd@SATA_____VBOX_HARDDISK____VB983bc998-aa600d6b  
 #  

Mirror ကို Boot တက္လို ့ရေအာင္ လုပ္ေပးပါမယ္။ ဒါ x86 အတြက္ပါ။ SPARC ေပၚမွာဆိုရင္ေတာ့ ဒီလိုမဟုတ္ပါဘူး။


 # installgrub /boot/grub/stage1 /boot/grub/stage2 /dev/rdsk/c0t1d0s0  
 stage1 written to partition 0 sector 0 (abs 16065)  
 stage2 written to partition 0, 273 sectors starting at 50 (abs 16115)  

HDD တလံုးထဲနဲ ့Boot လုပ္လို ့ရေအာင္ ဒီလိုင္းေလးကို /etc/system ဖိုင္ထဲမွာထည့္ထားပါမယ္။
set md:mirrored_root_flag=1


 echo “set md:mirrored_root_flag=1” >> /etc/system  


Disk Mirror လုပ္တာၿပီးပါၿပီ။ Configure လုပ္ခဲ့တာမွန္မမွန္ စစ္ခ်င္ရင္ Primary Disk ကို ၿဖဳတ္ၿပီး Secondary Disk နဲ ့boot တက္ၾကည့္ပါ။ Boot တက္လို ့ရတယ္ဆိုရင္ေတာ့အဆင္ေၿပပါၿပီ။

Tuesday, 14 August 2012

Login Script သို ့မဟုတ္ Shell Profile မ်ား

User Login မွာကိုယ္ run ေစခ်င္တဲ့ command ေတြကို ၀င္လိုက္တာနဲ ့ေအာ္တို run ေပးေအာင္သံုးတာၿဖစ္ပါတယ္။ User's Start-up ဖိုင္လို ့လည္းေခၚပါတယ္။


Environmental Variables ေတြ ေၾကၿငာတဲ့ပံုစံတခုမ်ိဳးေပါ့။ ဥပမာ က်ေနာ္က MySQL ကို အခုေလးတင္ပဲ Install လုပ္လိုက္ၿပီ ဆိုပါစို ့။ Install လုပ္လိုက္တဲ့ေနရာက /usr/local/mysql ပါ။ MySQL နဲ ့ပါတ္သတ္သမွ် binary file ေတြ library file ေတြ manual file ေတြအားလံုးကအဲဒီ /usr/local/mysql  ရဲ့ေအာက္မွာပဲရိွေနမွာပါ။ mysql ဆိုတဲ့ command ကို ရိုက္လို ့ရဖို ့အတြက္ က်ေနာ္ သူ ့ရဲ ့path တခုလံုးကို ရိုက္ရပါမယ္။

 /usr/local/mysql/bin/mysql  


အဲဒီလိုမရိုက္ခ်င္ဘူး mysql လို ့ပဲ တလံုးတည္းရိုက္လို ့ရခ်င္တယ္။ ဒါဆိုရင္ေတာ့ Shell ရဲ ့Environmental Variable မွာ MySQL ရဲ ့Binary Path ကို ေၾကၿငာေပးလိုက္ ရမွာၿဖစ္ပါတယ္။ ဘယ္လိုေၾကၿငာမလဲဆိုေတာ့
ဒီ command ကိုရိုက္ေပးရပါမယ္။

 PATH=$PATH:/usr/local/mysql/bin  

$PATH ကိုဘာလို ့ထည့္တာလဲဆိုေတာ့ အရင္ေၾကၿငာထားၿပီးသား Binary Path ေတြၿပန္ရေအာင္လို ့ပါ။ အရင္ေၾကၿငာထားၿပီးသား Binary Path ေတြကို ၾကည့္ခ်င္တယ္ဆိုရင္ ဒီ command ကိုရိုက္ၿပီး ၾကည့္လို ့ရပါတယ္။


 env | grep PATH  


ဒီလို ေၾကၿငာၿပီးသြားၿပီဆိုရင္ေတာ့ mysql လို ့တလံုးတည္းရိုက္လို ့ရသြားပါၿပီ။ ဒါေပမယ့္ ဒီ session ကို logout လုပ္လိုက္တာနဲ ့ခုနက ေၾကၿငာထားတဲ့ variable ကေပ်ာက္သြားမွာပါ။ အဲဒီလို မေပ်ာက္ခ်င္ဘူး login ၀င္လိုက္တိုင္း mysql ဆိုတဲ့ command ကိုရိုက္လို ့ရခ်င္တယ္ဆိုရင္ေတာ့ Home Directory ထဲမွာ  .profile ဆိုတဲ့ဖိုင္ကို create လုပ္ၿပီး အဲဒီဖိုင္ထဲမွာ command ကိုထည့္ေပးထားရပါမယ္။

.profile (or) .bash_profile နမူနာ
 PATH=/usr/local/bin:$PATH  
 export PATH

Solaris 10 မွာ Login ၀င္လိုက္ရင္ Shell ကေနၿပီးေတာ့ Linux မွာလိုမ်ိဳး User Name ၊  Host Name နဲ ့Path ေတြကိုမၿပေပးပါဘူး။ အဲဒီလိုမ်ိဳး ၿပတာလိုခ်င္ရင္ေတာ့ PS1 ကိုေၾကၿငာေပးရပါမယ္။ ကိုယ့္စိတ္ၾကိဳက္အေရာင္ကိုု ေရးနိုင္ပါတယ္။ ေအာက္မွာနမူနာေပးထားပါတယ္။

 PATH=/usr/local/bin:$PATH  
 export PATH  
 PS1="\[\033[1;31m\]\u@\h\033[0m\]:\[\033[1;32m\]\w$\[\033[0m\]";export PS1  


Default Shell ကို configure လုပ္ၿခင္း

ပထမဆံုးအၾကိမ္ Solaris 10 ကို login ၀င္တဲ့အခါ default shell က bourne shell ၿဖစ္ပါတယ္။ Default Shell အၿဖစ္ bash (Bourne Again Shell) ကိုလိုခ်င္ရင္ေတာ့ /etc/passwd ထဲမွာေၿပာင္းယူနိုင္ပါတယ္။ passwd ဖိုင္ထဲမွာ user configuration ကို ဒီလိုမ်ိဳး ေတြ ့ရမွာပါ။


 root:x:0:0:Super-User:/:/sbin/sh  

root            - ဒါကေတာ့ User Name ပါ။
                - ဒီဟာကေတာ့ User ရဲ ့Password ဟာ Encrypt လုပ္ထားတယ္ဆိုတာကိုၿပတာပါ။
0                  - ဒီဟာကေတာ့ UID (User ID)ပါ။
                - ဒီဟာကေတာ့ GID (Group ID) ပါ။ (GID /etc/group)
Super-User - ဒီဟာကေတာ့ Description ပါ။
/            - ဒီဟာကေတာ့ Home Directory ပါ။ login ၀င္၀င္ခ်င္းဒီ ေနရာကိုေရာက္မွာပါ။
/sbin/sh     - ဒီဟာကေတာ့ Default Shell ပါ။

 login shell ကို /bin/bash လို ့ေၿပာင္းလိုက္ ရင္ bash shell ကို Default Shell အေနနဲ ့ရမွာပါ။ တၿခား shell ေတြ ဥပမာ korn shell လို မ်ိဳးလိုခ်င္ရင္ /bin/ksh လို ့ေၿပာင္းလိုက္ရင္ရပါလိမ့္မယ္။ bash မွာ ေတာ့ command completion ကို နဲ ့လုပ္လို ့ရတာေၾကာင့္ေရာ ေတြကိုသြားရင္ အဆင္ေၿပတာေၾကာင့္မို ့လူၾကိဳက္မ်ားေလ့ရိွပါတယ္။ ဒါေပမယ့္ Unix Administrator ေတာ္ေတာ္မ်ားမ်ား ကေတာ့ Super User နဲ ့ bash shell ကို သံုးေလ့မရိွၾကဘူး။ command အမွားတခုကို လြယ္လြယ္ကူကူနဲ ့ issue လုပ္မိ လိုက္နိုင္တဲ့အတြက္ေၾကာင့္ပါ။