成功後に接続を正しく終了できないFTPサーバーにファイルを送信する方法は?

成功後に接続を正しく終了できないFTPサーバーにファイルを送信する方法は?

(SOから移動)

私の目標は、組み込みデバイスのFTPサーバーにファイルをアップロードすることです。このファイルは設定ファイルです。ファイルが承認されると、サーバーは再起動されます。この問題は、内蔵デバイスがソケットを開いたままにしたり、FTP接続を正しく終了できなかったりするために発生します。

サーバは、「受諾済み」を意味する応答コード150で応答する。その後、再起動しますが、ソケットは開いたままです。

私は解決策を探しています。 1つの解決策はFTPクライアントをCで手動で作成することであり、もう1つの解決策はBashスクリプトを介してUNIXに組み込まれたFTPクライアントを使用することです。以下のコメントで、誰かがカールまたはwget / wputの使用を提案しました。

最初の試み

最初の試みでは、CでFTPクライアントを作成することを検討しました。使用できるライブラリはありますか?周りを見回すと、ゴミライブラリがたくさん見えますが、良いライブラリがありません。

2回目の試み

別の試みでは、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あります。

3回目の試み

次に、次のアイデアを試しました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

これは少し良いです。カールを殺してもクライアントのようなものは残りませんftp

4回目の試み

今回の試みでは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 }
}

関連情報