摘要:本文對UNIX環境下SHELL腳本語言進行了簡要介紹,并舉例說明了如何利用SHELL腳本語言實現UNIX/Linux系統下氣象資料傳輸與處理。
關鍵詞:SHELL腳本;編程;氣象信息
中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2008)17-21460-04
1 引言
在氣象信息網絡系統中,氣象資料的收集、管理、數據分發、查詢統計等功能可以由多種方法實現。在UNIX系統下,利用SHELL語言編程,實現氣象資料傳輸與處理,可以達到簡單、易修改、運行穩定等效果。
2 SHELL簡介
SHELL是用戶一開始使用UNIX操作系統時就首先接觸到的,是用戶與系統之間的界面。它既是一種基于命令行的解釋程序,又是一種程序設計語言。它在編程時類似于DOS的批處理文件,但功能強大得多。SHELL程序腳本是以行為單位的,所寫的程序將被分解成一行一行來執行。腳本中的每一行可以是命令、注解或流程控制指令等。如一行未完,可以在行末加上“\\”續行。在腳本中的“#”后面的同行文字表示為注釋。在SHELL腳本中也可以設置變量,進行賦值、變量運算等。還可以加入條件測試、控制流、SHELL函數等。SHELL文件可以通過vi等編輯器直接編寫。編寫好的SHELL程序腳本,加上執行權限,不需編譯就可執行。
3 用SHELL腳本實現上行氣象信息傳輸
3.1 上行氣象信息傳輸
上行信息傳輸是指由下級氣象臺站向上級氣象信息網絡業務部門傳輸的各類探測資料、加工產品及其他有關信息。省級到國家級的信息傳輸是由省級收集省內各市、縣臺站上傳的各類氣象信息,根據相關的信息傳輸規定,通過氣象信息網絡系統,向國家氣象信息中心傳輸。由于氣象信息數據量龐大,在同一時間可能會有多種不同類型的資料等待傳輸。對于省臺、市臺來說,有必要把從下一級臺站收集來的氣象資料整理后向上一級傳送。
3.2 短文件名的資料傳輸
對于短文件名的資料,可以整理后通過9210業務應用系統提供的入口實現傳輸。下面是把氣象資料收集后合并,以新的本地文件名轉移到9210工程業務應用軟件上行入口目錄,以達到傳送目的的實例。其過程包含以下幾步:
$ vi send.sh
#定義變量
LOGDIR=/uplog
……
#取系統時間
dd='date+%d'
hh='date+%H'
mon='date+%m'
mm='date+%M'
#定義日志文件名、發送文件名
SENDLOG=$LOGDIR/sendmsg$dd.log
SPDEST=\"SP\"$dd$hh$mm\".CSY\"
UPDEST=\"UP\"$dd$hh$mm\".CSY\"
#通過條件語句判斷是否有待發的文件,如有,記日志,并將合并后新生成的文件送9210入口,由9210系統負責傳輸。如沒有,則退出。
if test -f $SOURDIR/*
then
mv $SOURDIR/* $SOURTEMP
else
exit
fi
cd $SOURTEMP
cp $SOURTEMP/* $MIOSRDB/msg
if test -f $SOURTEMP/S*
then
ls -l S*>>$SENDLOG#生成日志文件
echo \"以上文件發送為:$SPDEST\" >>$SENDLOG
#將合并后新生成的文件送9210入口
cat $SOURTEMP/S* >$DESTDIR/$SPDEST
ls $DESTDIR/$SPDEST>>$SENDLOG
rm $SOURTEMP/S*
fi
……
if test -f $SOURTEMP/*
then
mv $SOURTEMP/* $MVDIR
fi
exit
文件編輯完成后,給該文件加上可執行的權限,并將其加入用戶的crontab中定時啟動。
3.3 長文件名的傳輸
近年來,新增加了許多長文件名的資料,文件名往往由40多位字母組成,并由省級自行開發程序通過FTP傳輸。這些資料的傳輸也可以用SHELL實現。
vi ftpfile.sh
#!/bin/ksh
#定義變量
SOURDIR、TEMPDIR、BAKDIR、BJBACK
#獲取系統時間
yy='date +%y'
dd='date +%d'
hh='date +%H'
mon='date +%m'
mm='date +%M'
#定義文件名稱
SENDLOG=\"logdir/\"dqcf$yy$mon$dd\"snd.log\"
RCVLOG=\"logdir/\"dqcf$yy$mon$dd\"rcv.log\"
ERRLOG=\"logdir/\"dqcf$yy$mon$dd\"err.log\"
FILENAME=tmpdir/dqcffilename
FTMP=tmpdir/dqcftmp
#定義遠程目錄
REMOTEDIR=\"up\"
#查找本地文件記接收日志
cd $SOURDIR
lsnum='ls Z_CAWN*|wc -l'
if [ \"$lsnum\" -ge 1 ]
then
echo \"-----------------------\" >>$RCVLOG
ls -l Z_CAWN*>>$RCVLOG
mv $SOURDIR/Z_CAWN* $TEMPDIR
fi
cd $TEMPDIR
lsnum='ls Z_CAWN*|wc -l'
if [ \"$lsnum\" -ge 1 ]
then
# sleep 60
cp $TEMPDIR/Z_CAWN* $BAKDIR
ls -1 Z_CAWN* >$FILENAME
date>>$RCVLOG
echo \"------temp dir-------\" >>$RCVLOG
ls -1 Z_CAWN*>>$RCVLOG
integer i=1
while ((i<=$lsnum))
do
FNAME1='sed 1q $FILENAME'
sed 1d $FILENAME>$FTMP
cp $FTMP $FILENAME
#為避免傳輸過程中,文件被對方的處理程序同時訪問,需定義FTP用到的臨時文件名
FNAME2=$FNAME1\".tmp\"
#開始FTP傳輸
ftp -n -i << END
open 172.17.1.3
user newopr newopr123
lcd $TEMPDIR
cd $REMOTEDIR
put $FNAME1 $FNAME2
lcd $BJBACK
#從對方取回文件
get $FNAME2 $FNAME1
#對目標文件更名
rename $FNAME2 $FNAME1
close
END
#確認是否從對方調回文件,如果有,則刪除文件,記錄發送日志;否則保留在臨時目錄中,由于本程序在系統的crontab中2分鐘處理一次,且可達到時效要求,因此,本次未發出的文件留在臨時目錄中,可以等下次程序運行時一并處理。
cd $BJBACK
integer j=0
j='ls -1 $FNAME1|wc -l'
echo $j
if [ $j -ge 1 ]
then
rm -f $TEMPDIR/$FNAME1
date >> $SENDLOG
echo $FNAME1 >>$SENDLOG
rm -f $BJBACK/$FNAME1
else
#文件不能確認是否被傳送成功,記錄錯誤日志,并發布錯誤信息,值班人員可以看到。
date >> $ERRLOG
echo $FNAME1 >>$ERRLOG
wall \"Z_CAWN* not send out, please check network and view /bcsy/uplog/dqcfyymmdderr.log\"
fi
i=i+1
done
fi
exit
4 在SHELL中嵌入sed流編輯實現報類篩選
在眾多的氣象報類中,往往需要挑選出特定的一種氣象電報加以處理。或者,需要將臺站的代碼替換為本級代碼。這時,在SHELL中嵌入sed流編輯就大有幫助。區別于交互式的vi編輯器,sed是一種非交互式的文本編輯器,它的優勢在于它可以一次完成許多重復的操作,比如大量替換同樣的字符串。
4.1 篩選報文
下面是從文件中篩選出報頭為SXCI55的完整公報存入文件中。
$vi sed.sh
MSGDIR=\"/home/ljx/shdir/data\"
TEMP1=\"/home/ljx/shdir/sedsl1.tmp1\"
TEMP2=\"/home/ljx/shdir/sedsl2.tmp2\"
SLSH=\"/home/ljx/shdir/querysl.sh\"
dd='date +%d'
SLFILE=/home/ljx/shdir/sl$dd.txt
ls $MSGDIR >$TEMP1
#將從SXCI55到NNNN的內容保存在文件中
sed \"s:^:sed -n '/SXCI55/,/NNNN/p' $MSGDIR/:g\" $TEMP1 >$SLSH
ksh $SLSH>$TEMP2 2>/dev/1
asize='ls -s $TEMP2|cut -c3-4'
if [ $asize != 0 ]
then
#利用字符串替換給氣象電報加上起始行
sed \"s/SXCI55/ZCZC SXCI55/g\" $TEMP2>$TEMP1
cat $TEMP1>>$SLFILE
echo \" 'date' \~~~~~~~~~~~~~\">>$SLFILE
fi
rm $TEMP1 $TEMP2 $SLSH
exit
4.2 更改報頭行的發報地區代碼
可以將sed編輯內容寫入文件cgb.txt,在shell中調用,將氣象電報報頭行的BG開頭的臺站代碼替換成本級代碼。
vi cgb.txt
s/SMCI[0-9][0-9] BG[A-Z][A-Z]/SMCI59 BCSY/g
s/SICI[0-9][0-9] BG[A-Z][A-Z]/SICI59 BCSY/g
s/SXCI50 BG[A-Z][A-Z]/SXCI50 BCSY/g
s/SXCI55 BG[A-Z][A-Z]/SXCI55 BCSY/g
s/WSCI40 BG[A-Z][A-Z]/WSCI40 BCSY/g
……
在shell腳本中的調用語句可以是:sed –f cgb.txt 源文件名>目標文件名。
5 用SHELL腳本在終端上完成用戶界面
圖1是用SHELL腳本完成的簡單的報文查詢系統主界面。它用read命令接收鍵盤輸入實現人機交互,用print,echo,repeat等命令實現友好的用戶界面,用case條件語句實現不同選擇的分支功能。在這里就不一一列舉代碼了。
參考文獻:
[1] 阮戈, 林巍. 最新Unix程序設計與編程技巧[M]. 北京:清華大學出版社,2001:43-53.
注:本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文