(从SO移动)
我的目标是将文件上传到嵌入式设备中的 FTP 服务器。该文件是一个配置文件。文件被接受后,服务器将重新启动。造成这一挑战的原因是嵌入式设备使套接字保持打开状态,或者无法正确终止 FTP 连接。
服务器以响应代码 150 进行响应,这意味着“已接受”。然后它重新启动,但保持套接字打开。
我正在寻找解决方案。一种解决方案是用 C 语言手动编写 FTP 客户端,另一种解决方案是通过 Bash 脚本使用 UNIX 中内置的 FTP 客户端。在下面的评论中,有人建议使用curl 或wget/wput。
第一次尝试
在我的第一次尝试中,我考虑用 C 语言编写 FTP 客户端。有我可以使用的库吗?环顾四周,我看到很多垃圾库,但也许我错过了一个好的库。
第二次尝试
在另一次尝试中,我尝试使用 Bash 脚本来操作 FTP 客户端。
以下程序上传文件,但随后挂起
#!/bin/bash
HOST=192.168.1.10
USER='blah'
PASSWD='blah'
FILE='file1.conf'
ftp -n -i -v $HOST << EOT
ascii
user $USER $PASSWD
put $FILE myconfig.conf
bye
EOT
它是这么说的:
Connected to 192.168.1.10 (192.168.1.10).
220 FTP server ready.
530 access denied.
331 Password required.
230 User logged in.
local: somefile.txt remote: newname.txt
227 Entering Passive Mode (192,168,1,10,208,169)
150 ready to take file.
150 Accepting XML configuration file for upload.
818 bytes sent in 4.1e-05 secs (19951.22 Kbytes/sec)
<it hangs here>
如果我按 Ctrl-Z 它就会退出。如果我发送 Ctrl-C 或 Ctrl-X,则情况并非如此。当我执行 Ctrl-Z 时,它会让子进程挂起,我必须执行jobs -p | xargs kill -9
才能清理。
第三次尝试
接下来,我尝试了这个curl
想法:
$ curl -T file1.xml ftp://username:[email protected]/myfile.conf -v
这是回应:
* Trying 192.168.1.10...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.1.10 (192.168.1.10) port 21 (#0)
< 220 FTP server ready.
> USER admin
< 331 Password required.
> PASS PASS
< 230 User logged in.
> PWD
< 257 "/" is current directory
* Entry path is '/'
> EPSV
* Connect data stream passively
* ftp_perform ends with SECONDARY: 0
< 500 command not supported.
* Failed EPSV attempt. Disabling EPSV
> PASV
< 227 Entering Passive Mode (192,168,1,10,96,232)
* Trying 192.168.1.10...
* Connecting to 192.168.1.10 (192.168.1.10) port 24808
* Connected to 192.168.1.10 (192.168.1.10) port 21 (#0)
> TYPE I
< 200 command okay
> STOR myfile.conf
< 150 ready to take file.
} [583 bytes data]
* We are completely uploaded and fine
* Remembering we are in dir ""
< 150 Accepting XML configuration file for upload.
* server did not report OK, got 150
100 583 0 0 100 583 0 4827 --:--:-- --:--:-- --:--:-- 4858
* Connection #0 to host 192.168.1.10 left intact
curl: (18) server did not report OK, got 150
这还好一点。当我杀死curl时,它不会像客户端那样留下一些东西ftp
。
第四次尝试
在这次尝试中,我尝试了wput
。令我惊讶的是,我收到了段错误。
wput file1.conf ftp://username:[email protected]/myconfig.conf
--09:37:50-- `file1.conf'
=> ftp://admin:[email protected]:21/myconfig.conf
Connecting to 192.168.1.10:21... connected!
Logging in as admin ... Logged in!
==> LIST ... done.
Segmentation fault (core dumped)
答案1
expect
可以检测该bytes sent
行并在此时退出脚本:
#!/usr/bin/env expect
set HOST 192.168.1.10
set USER blah
set PASSWD blah
set FILE file1.conf
spawn -noecho ftp -n -i -v $HOST
# TODO possibly some error checking or prompt detection here...
send "ascii\r"
send "user $USER $PASSWD\r"
send "put $FILE myconfig.conf\r"
send "bye\r"
set timeout 60
expect {
# if paranoid confirm that the amount matches the size of file...
-ex "bytes sent" { exit }
timeout { exit 1 }
eof { exit 1 }
}