我们有一个 Perl 脚本,我们使用它(从 crontab 启动)好几年了,用来通过 Net::FTP 上传图片。最近我们开始注意到图片无法上传的问题,并且日志中出现错误。
在故障排除中,我发现目前该程序从 cmd 行启动时运行良好,但从 crontab 启动时会持续出错。在远程服务器上,我可以在 FTP 日志中看到连接仍然处于活动状态,客户端正在更改目录,但 STOR 命令从未像在正常情况下那样出现。在客户端,当发出 ftp->put 时,响应似乎是“227 进入被动模式”
我尝试了所有能想到的方法来查明原因(防火墙、临时端口、内存泄漏),但到目前为止,我唯一的解决方案是从 cmd 行手动运行它。
有谁知道这个问题可能是什么原因造成的?
更新:这是来自 Debug => 1 的一些输出:
从 crontab 运行时失败(最后一行“ERROR”来自 perl 脚本并包含 $ftp->message,即“进入被动模式”):
Net::FTP=GLOB(0xa004910)>>> CWD /images/shots
Net::FTP=GLOB(0xa004910)<<< 250 CWD command successful
Net::FTP=GLOB(0xa004910)>>> PASV
Net::FTP=GLOB(0xa004910)<<< 227 Entering Passive Mode (181,71,41,114,114,112).
ERROR: Couldn't put file /home/user/data/shot/212/212474.000078.jpg to f/4/f41891045708388275a0b1d1fe8a34fa.jpg on 127.0.0.1 because Entering Passive Mode (181,71,41,114,114,112).
从命令行运行并成功时:
Net::FTP=GLOB(0x8619170)>>> CWD /images/shots
Net::FTP=GLOB(0x8619170)<<< 250 CWD command successful
Net::FTP=GLOB(0x8619170)>>> PASV
Net::FTP=GLOB(0x8619170)<<< 227 Entering Passive Mode (181,71,41,114,113,179).
Net::FTP=GLOB(0x8619170)>>> STOR 5/6/569e214479a6f99f5bdf920e75f8351e.jpg
Net::FTP=GLOB(0x8619170)<<< 150 Opening BINARY mode data connection for 5/6/569e214479a6f99f5bdf920e75f8351e.jpg
Net::FTP=GLOB(0x8619170)<<< 226 Transfer complete
以下是执行此操作的脚本部分:
if ( ! ( $ftp->put($src_file, $target_file) ) ) {
print STDERR "ERROR: Couldn't put file $src_file to $target_file on $ftp_host because " . $ftp->message . "\n";
} else {
$mv_result = 1;
}
服务器运行 stunnel,因此 FTP 连接通过本地主机 (127.0.0.1) 上的端口发起
更新:好的,我搞清楚了是怎么回事,crontab 传入了一个参数,告诉它要使用哪个网络。结果发现该网络上的调制解调器出了问题,我愚蠢地没有在命令行上传递该参数,我们的默认网络运行良好。我们只需要一个新的调制解调器用于专用的上传线路。非常感谢你的帮助,Steffen。
答案1
服务器运行 stunnel,因此 FTP 连接通过本地主机 (127.0.0.1) 上的端口发起
我怀疑这是否可行。FTP 需要一个控制连接,您可以通过 stunnel 建立隧道。但除此之外,它还需要每次数据传输(STOR、RETR、LIST...)的数据连接。
您是否确实在工作命令行上使用相同的设置?
<<< 227 Entering Passive Mode (181,71,41,114,114,112).
这意味着,服务器希望在 IP 181.71.41.114、端口 28024(114*245+112)上建立数据连接。因此,Net::FTP 将尝试直接连接到此地址,因为它对隧道一无所知,也无法处理它。我假设您有 stunnel,因为直接连接到目标服务器不起作用,所以此连接尝试将失败。