<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
    主站蜘蛛池模板: 国产亚洲色视频在线| 野花高清在线电影观看免费视频| 日韩伦理片电影在线免费观看| 亚洲国产成人久久精品app| 99精品视频在线观看免费播放 | 亚洲最大的黄色网| 免费可以看黄的视频s色| 亚洲一级毛片在线播放| 香蕉视频在线观看免费国产婷婷| 亚洲精品无码专区在线| 啦啦啦手机完整免费高清观看| 精品亚洲国产成人av| 亚洲精品专区在线观看| 3344在线看片免费| 亚洲中文无码av永久| 日韩a级毛片免费视频| 亚洲阿v天堂在线2017免费| 国产av无码专区亚洲av桃花庵| 人妻无码久久一区二区三区免费 | 亚洲视频免费在线播放| 亚洲性无码AV中文字幕| 国产成人免费一区二区三区| 一区二区视频在线免费观看| 亚洲级αV无码毛片久久精品| 97在线视频免费| 九九精品国产亚洲AV日韩| 亚洲国产成人久久综合碰| 青柠影视在线观看免费高清| 亚洲a级在线观看| 亚洲国产成人久久综合一区77| 中文字幕无码毛片免费看| 亚洲中文字幕日本无线码| 亚洲男人第一无码aⅴ网站| 午夜爽爽爽男女免费观看影院| 亚洲 日韩经典 中文字幕 | 性色av无码免费一区二区三区| 免费一级做a爰片久久毛片潮| 亚洲精品免费观看| 国产精品公开免费视频| 999任你躁在线精品免费不卡| 国产精品亚洲天堂|