powershell下如何呼叫FTP,並等FTP作業完成
知道有powershell後,K了官方網站上所提供的文件後就來試試看。把原本一個作業改用powershell來處理,我只能說,雖然powershell跟以往比起來算跨了一大步,但是很多東西跟UNIX下來比還是礙手礙腳,當然也許跟我要處理的作業有關吧!
首先,我遇到的問題,就是要利用FTP,去取得遠方的資料回來處理。查了一下,有個要$的可以用,但一想到$還是算了,所以有找看看有無其他用.Net寫的class可以拿來利用。看了看,想想還是呼叫cmd 下的FTP算了…
一旦確定要用cmd呼叫FTP,就開始去做。這點不困難,在原本官方的user guide這文件中就有範例,但實際運作時,卻發現一個重大的問題!
因為在powershell所呼叫的ftp,由於是產生一個cmd的process去執行,所以,程式並不會等這ftp跑完,反而繼續我程式中後續的動作。偏偏我後面的動作會把ftp抓回來的資料搬一到其他地方去作為log之用!結果,就是powershell跑完了,但ftp卻『尚未』把資料抓回來。也就是說,powershell的程式,認為沒資料(因為ftp還沒把資料抓回來),所以就結束運作! :(
這點非常嚴重,找了不少資料,終於在MS的相關網站上找到解決之道…終於可以先確認ftp這段執行完畢後,原程序再繼續執行!下面就是處理方式~
PS:但是在我測試時,我還是遇到一個詭異的問題(有遇過幾次,但不常見)。因為我在程式一開始運作,會先產生一個暫存的子目錄,等到最後,把該目錄內的資料搬移(Move-item )到LOG的目錄內,最後再把該暫存子目錄砍掉(Remove-Item)。這樣的流程,並無問題,但…就是發生,檔案還沒移走,但後面的砍掉子目錄動作卻已經做了。造成我的log資料不完整。這樣的狀況,就很難理解
function getFtpFile{
$todayfile= $args[0]
$todayfile_m= $args[1]
$ftphost= "127.0.0.1"
$ftpuser= 'user'
$ftppass= 'password'
Set-Content -path ftp.txt $ftpuser
Add-Content -path ftp.txt $ftppass
Add-Content -path ftp.txt ("lcd $currentpath\ftp_temp")
Add-Content -path ftp.txt 'cd Receive'
#Add-Content -path ftp.txt "mget BKLT$todayfile*.txt"
Add-Content -path ftp.txt "get BKLT$todayfile_m.txt"
Add-Content -path ftp.txt 'bye'
$WshShell = New-Object -ComObject WScript.Shell
$theprocess= $WshShell.Exec("cmd /c ftp -i -s:$currentpath\ftp.txt $ftphost > $currentpath\$logfile" +"_ftp.log")
#下兩行的意義,就是要等CMD下的FTP執行完畢
$watching= get-process -id $theprocess.ProcessID
$watching.waitforexit()
# 改檔名,作為log
$strcmd="rename-item $currentpath\ftp.txt -newname $logfile"+'_'+"ftp.txt"
invoke-expression $strcmd
}
首先,我遇到的問題,就是要利用FTP,去取得遠方的資料回來處理。查了一下,有個要$的可以用,但一想到$還是算了,所以有找看看有無其他用.Net寫的class可以拿來利用。看了看,想想還是呼叫cmd 下的FTP算了…
一旦確定要用cmd呼叫FTP,就開始去做。這點不困難,在原本官方的user guide這文件中就有範例,但實際運作時,卻發現一個重大的問題!
因為在powershell所呼叫的ftp,由於是產生一個cmd的process去執行,所以,程式並不會等這ftp跑完,反而繼續我程式中後續的動作。偏偏我後面的動作會把ftp抓回來的資料搬一到其他地方去作為log之用!結果,就是powershell跑完了,但ftp卻『尚未』把資料抓回來。也就是說,powershell的程式,認為沒資料(因為ftp還沒把資料抓回來),所以就結束運作! :(
這點非常嚴重,找了不少資料,終於在MS的相關網站上找到解決之道…終於可以先確認ftp這段執行完畢後,原程序再繼續執行!下面就是處理方式~
PS:但是在我測試時,我還是遇到一個詭異的問題(有遇過幾次,但不常見)。因為我在程式一開始運作,會先產生一個暫存的子目錄,等到最後,把該目錄內的資料搬移(Move-item )到LOG的目錄內,最後再把該暫存子目錄砍掉(Remove-Item)。這樣的流程,並無問題,但…就是發生,檔案還沒移走,但後面的砍掉子目錄動作卻已經做了。造成我的log資料不完整。這樣的狀況,就很難理解
function getFtpFile{
$todayfile= $args[0]
$todayfile_m= $args[1]
$ftphost= "127.0.0.1"
$ftpuser= 'user'
$ftppass= 'password'
Set-Content -path ftp.txt $ftpuser
Add-Content -path ftp.txt $ftppass
Add-Content -path ftp.txt ("lcd $currentpath\ftp_temp")
Add-Content -path ftp.txt 'cd Receive'
#Add-Content -path ftp.txt "mget BKLT$todayfile*.txt"
Add-Content -path ftp.txt "get BKLT$todayfile_m.txt"
Add-Content -path ftp.txt 'bye'
$WshShell = New-Object -ComObject WScript.Shell
$theprocess= $WshShell.Exec("cmd /c ftp -i -s:$currentpath\ftp.txt $ftphost > $currentpath\$logfile" +"_ftp.log")
#下兩行的意義,就是要等CMD下的FTP執行完畢
$watching= get-process -id $theprocess.ProcessID
$watching.waitforexit()
# 改檔名,作為log
$strcmd="rename-item $currentpath\ftp.txt -newname $logfile"+'_'+"ftp.txt"
invoke-expression $strcmd
}
留言