July 12, 2012

Input Output

File Descriptor


Unix နှင့် Linux OS များတွင် File Descriptor ဟု အမည်ရသော Input Output သုံး ပရိုဂရမ်ကို ပိုင်ဆိုင်ပြီး၊ Process များနှင့် ထို File Descriptor များအား ပူတွဲထားလေ့ရှိ၏။ အကယ်၍ ပရိုဂရမ်တစ်ခုမှ ဖိုင်တစ်ခုဆီသို့ Input Output လုပ်လိုသည့် အခါတိုင်း ပရိုဆက်များသည် ထို File Descriptor အား အသုံးပြု၍ အသုံးပြုလိုသော File ဆီသို့ Access လုပ်လေ့ရှိပါသည်။

File Descriptor များအား သုညမှ ငါး အထိ နံပါတ်များဖြင့် သက်မှတ်ထားပြီး၊ 0, 1, 2 အထိ ၃မျိုးသည် ကြိုတင် သတ်မှတ်ပြီး ဖြစ်၏။ ပရိုဆက်တစ်ခုခုက အလုပ်လုပ်တိုင်း ထို File Descriptor များသည် အသုံးပြုရန် အသင့် အနေအထားသို့ ပြောင်းလည်းသွားမည် ဖြစ်ပါသည်။

File Descriptor နံပတ် 0 သည် Standard Input ဖြစ်ပြီး၊ ကီးဘုတ်ဆီမှ ရိုက်သွင်းလိုက်သော Input များအား Shell ပရိုဂရမ်ဆီသို့ လက်ဆင့်ကမ်းပေးပါသည်။


တဖန် နံပတ် 1 သည် Standard Output ဖြစ်ပြီး Terminal မျက်နှာပြင်တွင် Output လုပ်စေပါသည်။ Shell ပရိုဂရမ်များအတွင်းမှ ကွန်မန်းများ၏ ရလဒ်များသည် Terminal ပေါ်တွင် ဖော်ပြနိုင်ခြင်းသည် Shell အား အလုပ်လုပ်နေသော ပရိုဆက်သည် Standard Output အား အသုံးပြု၍ Output လုပ်နေခြင်းကြောင့် ဖြစ်ပါသည်။

နံပါတ် 2 သည် Standard Error ဖြစ်ပါသည်။ Standard Error သည်လည်း Terminal ၏ မျက်နှာပြင်တွင် Output လုပ်ပါသည်။ Standard Output နှင့် Standard Error အား ခွဲခြား၍ Output လုပ်လိုသည့်အခါမျိုးတွင် အသုံးပြုနိုင်ရန် အတွက် File Descriptor အား သီးခြားစီ သတ်မှတ်ထားခြင်း ဖြစ်ပါသည်။


Redirection


အထက်ပါ File Descriptor တွင် ပုံမှန်အားဖြင့် Standard Input အား ကီးဘုတ်မှ၊ Standard Output အား Terminal ဆီသို့ ထုတ်လုပ်ပေးကြောင်း ဖော်ပြပေး၏။ ဤကဲ့သို့ Input Output များအား ပုံမှန် အသုံးပြုရာနေရာမှ  ပြောင်းပြီး အသုံးပြုခြင်းအား Redirection ဟု ခေါ်ဆိုပါသည်။ Shell ပရိုဂရမ်များတွင် Redirection အား အသုံးပြု၍ Input များအား File မှ တဆင့် အသုံးပြုခြင်း၊ Output များအား အခြားသော ဖိုင်များတွင် ရေးသားစေခြင်း အစရှိသည့် လုပ်ဆောင်ချက်များအား လုပ်ဆောင်စေနိုင်ပါသည်။

Redirection ကို အသုံးပြုရာတွင် Output အား [ > ] ဟု သော်၎င်း၊ Input အား [ < ] ဟု သော်၎င်း ရေးသားနိုင်ပါသည်။


အထက် ဖော်ပြပါအတိုင်း echo "hello shell" ဟု ရေးသားရာတွင် Standard Output ကို အသုံးပြုပါသဖြင့် ရရှိလာသော ရလဒ်အား Terminal တွင် ဖော်ပြပေးစေပါသည်။ တဖန် echo "hello shell" > test.txt ဟု ရေးထားခြင်းသည် echo "hello shell" ၏ ရလဒ်အား test.txt ဟု အမည် ရသော ဖိုင်ဆီသို့ Redirect လုပ်နေခြင်း ဖြစ်ပါသည်။ ဤနည်းအားဖြင့် echo ၏ ရလဒ်အား test.txt တွင် အသစ်ရေသားမည် ဖြစ်ပါသည်။ ထို့ကြောင့် cat test.txt ဟု ရိုက်ပြီး အတွင်းရှိစာသားများအား ဖော်ပြစေရာတွင် hello shell ဟု ဖော်ပြနိုင်ခြင်း ဖြစ်ပါသည်။

တဖန် redirection များတွင် > ဟု ရေးသားထားလျှင် ဖိုင်အား အသစ် ဖွင့်၍ ရေးသားမည်ဖြစ်ပြီး၊ >> ဟု ရေးသားထားပါက ထိုဖိုင်၏ နောက်ဆုံးစာကြောင်းမှ တဆင့် ဆက်၍ ရေးသားသွားမည် ဖြစ်ပါသည်။

အလားတူပင် < ဟု ရေးသားထားပါက Input ကို ရည်ညွှန်းခြင်း ဖြစ်ပါသည်။ ဥပမာအားဖြင့် command < file ဟု ရေးထားပါက file အတွင်းမှ ခေါ်ယူပြီး command ဆီသို့ ပါရာမီတာ အဖြစ် အသုံးပြုနိုင်မည် ဖြစ်သည်။ တဖန် << သည် ရေးသားထားသည်ကို တိုက်ရိုက်ခေါ်ယူသွင်းခြင်း ဖြစ်ပါသည်။ command << word ဟု ရေးသားထားပါက word အား ပါရာမီတာအဖြစ် command ဆီသို့ ပေးနိုင်မည် ဖြစ်ပါသည်။

ကျွှန်တော်တို့ အစပိုင်းတွင် File Descriptor များအား နံပါတ်များ သက်မှတ်ထားသည်ဟု ဖော်ပြခဲ့သည်ကို မှတ်မိပါဦးမည်။ အမှန်ဆိုလျှင် Standard Output အား ဖိုင် သို့ Redirect လုပ်မည်ဆိုလျှင် အောက်ပါအတိုင်း ရေးရန် လိုအပ်ပါသည်။
command 1> file
အကယ်၍ File Descriptor များအား ရေးသားထားခြင်း မရှိပါက၊ Default အနေဖြင့် Standard Output အား အသုံးပြုမည် ဖြစ်သောကြောင့် command > file ဟု ရေးသားထားခြင်းဖြင့် Standard Output အား file ဆီသို့ Redirect လုပ်ပေးနိုင်ခြင်း ဖြစ်ပါသည်။ အလားတူစွာပင် command < file ဟု ရေးသားထားခြင်းသည်လည်း Standard Input အား file ဆီမှ Redirect လုပ်ယူခြင်းပင် ဖြစ်ပါသည်။ ထို့ကြောင့် command 0< file ဟု ရေးသားခြင်းနှင့် ထပ်တူပင် ဖြစ်ပါသည်။

အသုံးများသော ရေးသားပုံမှာမှာ အောက်ပါအတိုင်း ဖြစ်ပါသည်။

အတိုကောက်  ပုံမှန် ရေးသားပုံ ရှင်းလင်းချက်
 > file 1> file Standard Output အား file တွင် ရေးသားပါမည်။
 >> file 1>> file Standard Output အား file တွင် ဖြည့်စွက် ရေးသားပါမည်။
 >&m 1>&m Standard Output အား နံပါတ် m မြောက် File Descriptor တွင် ရေးသားပါမည်။
 >&- 1>&- Standard Output အား close လုပ်ပါမည်။
 < file 0< file Standard Input အား file မှ အသုံးပြုပါမည်။
 <&m 0<&m Standard Input အား နံပါတ် m မြောက် File Descriptor မှ အသုံးပြု ပါမည်။
 <&- 0<&- Standard Input အား close လုပ်ပါမည်။
 << word 0<< word Here Document ဟု ခေါ်ဆိုပြီး၊ စာလုံးရှည်များအား Standard Input မှ အသုံးပြုလိုသည့်အခါတွင် အသုံးပြုပါသည်။


Output နမှုနာ


ကျွှန်တော်တို့ ဒီတစ်ခေါက် Shell ပရိုဂရမ်အတွင်းမှ log ရေးနိုင်သော ဖန်ရှင်အား ရေးသား၍ File Output ၏ နမှုနာကို ရေးသားကြည့်ပါမည်။

log.func
LOG()
{
        #log directory
        LOG_DIR=./

        #parameter data
        FILENM=`basename $0`
        MSG=$1

        #var
        LOG_DATE=`date '+%Y-%m-%d'`
        LOG_TIME=`date '+%H:%M:%S'`
        LOGFILE="${LOG_DIR}${LOG_DATE}_`basename $0 .sh`.log"

        printf "%-10s %-8s %-14s %-50s\n" \
        "${LOG_DATE}" "${LOG_TIME}" "${FILENM}" "${MSG}" >>${LOGFILE}
}

GetYM()
{
        SYSTEM_MONTH=`date '+%Y%m'`
        echo ${SYSTEM_MONTH}
}

GetYMD()
{
        SYSTEM_DATE=`date '+%Y%m%d'`
        echo ${SYSTEM_DATE}
}
ဤ နမှုနာထဲတွင် LOG အမည်ရသော ဖန်ရှင်အား ရေးသားထားပြီး၊ ၎င်းအား အခြားသော Shell ပရိုဂရမ်များမှ ခေါ်ယူခြင်း အားဖြင့် Log ဖိုင်များတွင် လိုအပ်သော log message များအား ရေးသားစေခြင်း ဖြစ်ပါသည်။ LOG ဖန်ရှင် အထဲတွင် basename ကွန်မန်းဖြင့် ဖိုင်အမည်ကို ရယူကာ၊ log message အတွင်းတွင်သော်၎င်း၊ log ဖိုင် အမည်တွင်၎င်း အသုံးပြုထားပါသည်။ တဖန် log message အား log ဖိုင် တွင် ရေးသားရာတွင် >> အား အသုံးပြုထားပါသည်။

GetYM နှင့် GetYMD မှာ နမှုနာတွင် အသုံးပြုရန်အတွက် ဖန်ရှင်များဖြစ်ကြပြီး၊ နှစ်လ နှင့် နှစ်လရက်ကို ရရှိနိုင်ပါသည်။

sample.sh
#!/bin/sh
#read common file
. ./log.func

#start log
LOG "Sample Application START"

#getYM
YM=`GetYM`
mkdir ${YM}
LOG "Make Directory is finished"

#getYMD
YMD=`GetYMD`
touch ${YM}/${YMD}
LOG "Creating file is finished"

LOG "Sample Application END"
ဤ နမှုနာ အတွင်းမှာမူ အသုံးပြုလိုသော common file တစ်ခုဖြစ်သည့် log.func အား . ကွန်မန်းအား အသုံးပြု၍ ခေါ်ယူထားပါသည်။ ပြီးပါက LOG ဖန်ရှင်အား အသုံးပြု၍ Log Message များအား ရေးသားစေပါသည်။ အတွင်းမှာမူ နမှုနာအနေဖြင့် ဒိုင်အတ္တရီနှင့် ဖိုင်များအား ရေးသားစေပြီး၊ အသီးသီး log message များအား ရေးသားစေပါသည်။

ကျွှန်တော်တို့ အထက်ပါ နမှုနာကို အလုပ်လုပ်ကြည့်စေပါမည်။


အထက်ပါအတိုင်း ရက်စွဲဖြင့် ဒိုင်အတ္တရီ တစ်ခုကို ရေးသားနိုင်ပြီး၊ log ဖိုင်ကိုလည်း ရေးသားနိုင်သည်ကို တွေ့ရပါသည်။


ဖိုင် Input နမှုနာ


ဒီနမှုနာတွင် အချက်အလက်များအား ဖိုင်အတွင်းတွင် သိမ်းဆည်းထား၍ ထိုအချက်အလက်များအား ဖတ်ယူကာ အလုပ်လုပ်စေတတ်သော နမှုနာတစ်ခုကို ရေးသားပါမည်။

sample.sh
#!/bin/sh

LIST=./abc.list

GETSTR()
{
        if [ $# -ne 1 ]
        then
                return 1
        else
                ID=$1
        fi

        while read F1 F2
        do
                if [ "${F1}" = "${ID}" ]
                then
                        echo ${F2}
                        break
                fi
        done < ${LIST}
}

STR002=`GETSTR 002`
STR003=`GETSTR 003`
STR005=`GETSTR 005`

echo "STR002=${STR002}"
echo "STR003=${STR003}"
echo "STR005=${STR005}"
အထက်ပါ နမှုနာထဲတွင် GETSTR ဟု အမည်ရသော ဖန်ရှင်တစ်ခုအား ရေးသားထားပါသည်။ ဖန်ရှင်အတွင်းတွင် စာကြောင်း၇ဖြင့် အကယ်၍ ဖန်ရှင်အား ခေါ်ယူသည့် ပါရာမီတာ အရေအတွက်သည် ၁ခုထက်နည်းပါက ဆက်မလုပ်ပဲ 1 ကို return လုပ်မည် ဖြစ်ပါသည်။ သို့မဟုတ်ပါက ကိန်းရှင် ID တွင် နံပါတ်တစ်ပါရာမီတာအား အစားထိုးပါမည်။ တဖန် စာကြောင်း ၁၄တွင် while ဝါကျဖြင့် ကိန်းရှင် F1နှင့် F2 အား ခေါ်ယူပါသည်။

ထို ကိန်းရှင်များမှာ စာကြောင်း ၂၁တွင် ရေးထားသည့်အတိုင်း LIST ကိန်းရှင်မှ input လုပ်ထားပါသည်။ LIST ၏ တန်ဖိုးသည် ./abc.list ဖြစ်ပါသဖြင့် abc.list ဖိုင်၏ အတွင်းရှိစာသားများဖြင့် while ဝါကျအား အလုပ်လုပ်စေမည် ဖြစ်ပါသည်။ အတွင်းပိုင်းတွင် F1 ၏တန်ဖိုးနှင့် F2 သည် တူညီပါက F2 အား echo လုပ်နေခြင်း သာဖြစ်ပါသည်။ အောက်ပါအတိုင်း abc.list ဖိုင်အား ရေးသားပါမည်။


အထွေအထူးမဟုတ်။ ကီးနှင့် တန်ဖိုးအား တွဲထားသော Map တစ်ခုကဲ့သို့ပင် ဖြစ်၏။ ရေးသားထားသော Shell အား အလုပ်လုပ် ကြည့်စေသောအခါ အောက်ပါအတိုင်း တွေ့ရပါမည်။



ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်။
မင်းလွင်

No comments:

Post a Comment