<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 188,comments - 176,trackbacks - 0

    在編寫shell腳本的時候,有時候需要在執行完shell腳本(手工執行或利用crontab定時執行),需要服務器上制定目錄下的文件或子目錄進行刪除操作,以免下次執行時產生數據沖突。

    現需要編寫一個shell腳本,完成以下功能:
    [1]從系統B那邊將指定目錄下的文本文件FTP到系統A本地服務器的制定目錄下。
    [2]FTP到本地后,執行系統A本地上的shell腳本,將文本文件中的信息入到系統A本地映射的數據庫中。
    [3]入庫完畢后,再FTP到系統B將遠程的0指定目錄下的那個文本文件刪除。
    [4]系統A上shell將其本地的相關目錄下的文文本件和子目錄的內容刪除,防止下次執行產生數據重復和沖突。
    注:系統A和B都是HP-Unix,且系統A上的shell_a和系統B上的shell_b執行時間為每天晚上23:00之后,它們時間差大概十分鐘(如 在23:00時刻執行shell_b,到23:10時刻執行shell_a)。

    上面步驟當中涉及到刪除操作的有[3]和[4],而問題就發生在第[4]步。第[4]步中的刪除系統A本地上目錄下的文件,這里我是用rm來進行刪除的。首先我的shell腳本部署在系統A的:/home/coner/blackall/目錄下,名稱為black_all.sh。
    腳本中對于刪除本地文件的代碼如下(注:blackall目錄下的data 和 ctl子目錄已經存在)

    #!/bin/sh
    sqlldr_dir=`pwd`
    sqlldr_data_dir
    ="data"

    cd 
    $sqlldr_dir/$sqlldr_data_dir
    rm 
    -*.txt

    對于上面代碼,當shell腳本手工執行的時候,結果沒有任何問題,sqlldr_dir的值此時為腳本所在的路徑:/home/coner/blackall/,故cd $sqlldr_dir/$sqlldr_data_dir可以成功登錄到/home/coner/blackall/data下,再進行rm -f *將data子目錄下的所有文件刪除(文件不分前綴和后綴名)。但對于定時任務,要用crontab部署的情況下呢?
    問題就出在這里,筆者測試,利用crontab將該shell部署后,設置定時時間,到點后通過重定向生成的日志中,看到sqlldr_dir打印到日志中的值并不是/home/coner/blackall/,而是/home/coner。故可以推斷到,上面的刪除代碼,當用定時任務部署的時候,$sqlldr_dir/$sqlldr_data_dir的值就為/home/coner/data,而在系統A上/home/coner目錄下沒有此目錄,即cd 操作失敗,系統拋出異常(及時碰巧有這個目錄data,也是誤刪除文件的操作)。接著執行下面的rm -f *。此時,crontab命令對于該shell腳本所在位置的解析為/home/coner,故在執行rm -f *的時候就將/home/coner目錄下的所有文件全部刪除掉了,這樣就造成誤刪除文件的惡果。

    郁悶+揪心中...不過幸運的是,執行腳本前有做手工的文件備份。

    鑒于上面情況,筆者將shell腳本重新進行了審核,將sqlldr_dir=`pwd`換成sqlldr_dir=/home/coner/blackall,并對cd操作加上異常保護。代碼如下:

    #!/bin/sh
    sqlldr_dir=/home/coner/blackall
    sqlldr_data_dir
    ="data"

    cd 
    $sqlldr_dir/$sqlldr_data_dir >/dev/null 2>&1
    if [ $? -ne 0 ]
         then 
              echo 
    "the path of $sqlldr_dir/$sqlldr_data_dir invalid.."
              
    exit  
         
    else
              echo 
    "begin rm -f $sqlldr_dir/$sqlldr_data_dir/*.txt"
              rm 
    -*.txt
    fi

    或者在能確定路徑的情況下直接寫成定值: rm -f /home/coner/blackall/data/*.txt


    對于crontab命令執行定時任務,和登錄系統后,在用戶coner下手工執行shell是有區別的。前者在執行腳本時候,解析pwd命令只能解析到當前用戶即coner目錄為止,即上面的sqlldr_dir的值為/home/coner,而在用戶coner下手工執行shell是在解析pwd命令時可以正常解析到/home/coner/blackall。這個和shell腳本初始化.profile(Unix)或.bash_profile(Linux)沒有關系,即使在腳本中進行下面的初始化操作:

    # if HP-UX and AIX
    if [ -/home/zxin10/.profile ]
     then
              echo 
    "INIT profile TO UNIX"
              
    . /home/zxin10/.profile
    fi
    # if Linux
    if [ -/home/zxin10/.bash_profile ]
               then
              echo 
    "INIT bash_profile TO LINUX"
               
    . /home/zxin10/.bash_profile
    fi

    在用crontab執行腳本時,解釋pwd的時候,sqlldr_dir的值還是/home/coner。
    上面的初始化腳本,主要是針對利用crontab部署定時任務時,因為crontab啟動的命令并不讀當前的.profile,因此所有的程序需要的環境變量需要用程序或shell自己去設置(和手工執行shell不同,手工執行shell是在某個登錄用戶下執行的,登錄該用戶之后,就已經初始化了環境變量配置文件),那么在shell中調用第三方軟件的一些命令(如Oracle的sqlplus和sqlldr等命令)時,如果程序中直接寫成sqlplus或sqlldr命令來調用時,腳本是識別不到這些命令的。在定時任務執行完畢后的系統郵件(mail命令查看)中會提示找不到該命令。解決方法就是在執行shell腳本的業務邏輯前先初始化操作系統的環境變量配置文件.profile或.bash_profile。如果不初始化也可以,那么在shell中調用這些命令時,需要將其寫成絕對路徑,如:/home/oracle/oracle92/bin/sqlldr這樣的形式。

    上面是我個人的實踐和理解,歡迎大家提出好的建議,共同參考學習。



    posted on 2008-05-18 17:18 cheng 閱讀(3263) 評論(0)  編輯  收藏 所屬分類: Unix/Linux
    主站蜘蛛池模板: 国产午夜精品理论片免费观看| 亚洲欧美成人av在线观看| 无遮挡国产高潮视频免费观看| 免费电视剧在线观看| 亚洲中字慕日产2021| 亚洲免费网站观看视频| 亚洲一卡2卡3卡4卡乱码 在线 | 亚洲精品尤物yw在线影院| 美女裸免费观看网站| 亚洲国产精品一区二区三区久久| 国产成人va亚洲电影| 亚洲人成色77777在线观看大| 一级特黄录像免费播放肥| 亚洲国产精品无码成人片久久| 免费看男人j放进女人j免费看| 亚洲国产人成在线观看69网站| 日本视频一区在线观看免费| 亚洲中文字幕一二三四区苍井空 | 亚洲天堂免费在线视频| 99精品视频在线观看免费| 久久精品国产亚洲AV香蕉| 久久电影网午夜鲁丝片免费| 精品在线免费视频| 国产亚洲一区二区手机在线观看| 99久久人妻精品免费二区| 亚洲无吗在线视频| 亚洲精品无码你懂的网站| 69视频在线观看免费| 亚洲AV色欲色欲WWW| 综合亚洲伊人午夜网| 18禁美女裸体免费网站| 亚洲av最新在线观看网址| 亚洲愉拍99热成人精品热久久| 99re6在线视频精品免费下载| 亚洲人成电影网站色| 狠狠亚洲婷婷综合色香五月排名| 最近免费中文字幕大全免费| 毛片亚洲AV无码精品国产午夜| 亚洲丁香色婷婷综合欲色啪| 女性无套免费网站在线看| 你好老叔电影观看免费|