如何将文件发送到成功后无法正确终止连接的 FTP 服务器?

如何将文件发送到成功后无法正确终止连接的 FTP 服务器?

(从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 }
}

相关内容