我經(jīng)常用ftp從一臺(tái)電腦傳輸一個(gè)文件到另一臺(tái)電腦拓哺。有時(shí)我用命令行交互模式執(zhí)行操作,但更多時(shí)候,我喜歡寫(xiě)一個(gè)腳本來(lái)做這件苦差事沼侣。這個(gè)任務(wù)著實(shí)使我蒙逼了一陣子,但我最終解決了那些坑歉秫。我沒(méi)有見(jiàn)過(guò)這方面有關(guān)的文檔蛾洛,所以我寫(xiě)了這個(gè)供你參考。</br>
問(wèn)題所在
我在過(guò)程中遇到的關(guān)鍵問(wèn)題是,你要提供一個(gè)密碼給ftp服務(wù)器.典型的ftp客戶端(比如unix下的,linux下的,solaris下的,NetBSD下的)都從/dev/tty
讀取密碼.
(non-working) 腳本例子
#!/bin/sh
HOST='ftp.users.qwest.net'
USER='yourid'
PASSWD='yourpw'
FILE='file.txt'
ftp $HOST <<END_SCRIPT
user $USER
$PASSWD
put $FILE
quit
END_SCRIPT
exit 0
上面的腳本并不會(huì)完成工作,無(wú)論是執(zhí)行在前景還是作為定時(shí)任務(wù)執(zhí)行在背景,都不會(huì)工作.</br>
/dev/tty
是一種奇怪的設(shè)備.每一個(gè)進(jìn)程(精確的說(shuō)是每一個(gè)進(jìn)程組)有不同的/dev/tty
,你不能天真地讓ftp客戶端從某個(gè)文件中(比如here document)讀取密碼.當(dāng)在終端執(zhí)行時(shí),上面的腳本會(huì)掛著,因?yàn)樗鼜?code>/dev/tty讀取密碼,終端構(gòu)成了腳本的/dev/tty
,所以腳本等著鍵盤(pán)輸入.
(working) 腳本例子
#!/bin/sh
HOST='ftp.users.qwest.net'
USER='yourid'
PASSWD='yourpw'
FILE='file.txt'
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
put $FILE
quit
END_SCRIPT
exit 0
訣竅所在
不需要ftp客戶端從/dev/tty
讀取密碼需要耍兩個(gè)把戲:</br>
- 使用
-n
選項(xiàng)連接ftp客戶端以阻止ftp客戶端立即登錄.這樣,ftp客戶端就不要你輸入一個(gè)用戶名和密碼了.所以沒(méi)有用到/dev/tty
- 使用ftp客戶端命令
quote
發(fā)送用戶名和密碼.</br>
你必須在開(kāi)頭和結(jié)尾加上END_SCRIPT
,盡管命令已經(jīng)縮進(jìn)了,還是要加上.</br>
進(jìn)一步改良
上面的腳本會(huì)從ftp客戶端涌出許多輸出到標(biāo)準(zhǔn)輸出,即便它運(yùn)行良好轧膘。運(yùn)行上面的腳本會(huì)立刻顯示許多亂七八糟的內(nèi)容給用戶钞螟,改良一下的方法是把輸出輸?shù)狡渌牡胤饺ィ竭h(yuǎn)越好:
ftp -n $HOST > /tmp/ftp.worked 2> /tmp/ftp.failed <<END_SCRIPT
還可以改良一下處理錯(cuò)誤,就是處理ftp客戶端的退出狀態(tài).
ftp -n $HOST > /tmp/ftp.worked 2> /tmp/ftp.failed <<END_SCRIPT
blah blah
END_SCRIPT
EXITSTATUS=$?
if [ $EXITSTATUS != "0" ]
then
# handle the error...
fi
then
里面的代碼一般不會(huì)執(zhí)行,大多數(shù)時(shí)候ftp客戶端都會(huì)返回狀態(tài)0
.這只會(huì)給你沒(méi)用的信息:文件傳輸失敗了,但腳本也不能查出問(wèn)題.</br>
下面的方法可以證實(shí)文件是否傳輸成功:
#!/bin/sh
ftp -n << END_SCRIPT
open $1
user $2 $3
put $4
get $4 retrieval.$$
bye
END_SCRIPT
if [ -f retrieval.$$ ]
then
echo "FTP of $4 to $1 worked"
rm -f retrieval.$$
else
echo "FTP of $4 did not work"
fi
不合格的傳輸會(huì)留下文件.
代替腳本
我在usenet 文章上看到另一種方法:
#!/bin/sh
USER=userid
PASSWD=userpw
ftp -n f2dev <<SCRIPT
user $USER $PASSWD
binary
get some.file
quit
SCRIPT
這里依然用到-n
把戲,但是它發(fā)送用戶名和密碼都在一條ftp命令