使用FTP递归上传文件到远程服务器

3
我目前处于一种非常有限的服务器访问情况下,但需要上传和下载包含在单个目录结构中的大量文件。 由于我没有SSH访问权限,因此无法使用SCP,而rsync也不可行。
我目前正在使用ncftpput,这很好,但似乎速度相当慢(尽管连接很快)。
是否有另一种/更好的方法可以考虑?
(如果已经涉及到此问题,请接受我的道歉,我在发布之前进行了快速搜索,但没有找到明确回答我的问题的内容)

2
对于ncftp,您是否使用“put -R”命令进行递归目录上传? - DmitryK
我确实是 - 我认为问题的一部分在于FTP相当陈旧..因此可能没有理想的解决方案。 - codeinthehole
5个回答

4

非常感谢这些..我刚刚编译了YAFC,它看起来非常不错。 - codeinthehole

2
如果您的网络连接良好,我建议通过GNOME或KDE文件管理器挂载FTP服务器,否则可以使用CurlFtpFS。然后您就可以将其视为另一个文件夹。

这是一个糟糕的答案。这样做绝对比FTP慢,而且风险更大,特别是在处理大量数据时,因为它不支持中断后恢复。如果他没有SSH访问权限,那么他如何配置挂载呢? - Benubird
不需要进行服务器配置。服务器已经为FTP配置好了。而重点不是让事情变得更快,而是让它们变得更容易。使用CurlFtpFS挂载后,可以使用标准的Unix工具,如cp和rsync。我确实说过它在良好的连接下效果最佳。 - Ryan C. Thompson

1

我不熟悉ncftpput。对于非交互式FTP,我一直使用Perl Net::FTP模块--http://perldoc.perl.org/Net/FTP.html

这将更快,因为您可以登录,然后一次性执行所有传输(从粗略的扫描中看来,您会为每个文件get/put执行ncftpput)。

只需记住永远不要使用ASCII混淆!这是默认设置,因此请使用:

$ftp->binary

ASCII混淆需要和MySQL自动时区解释一起消失。


0

由于我总是遇到这个问题,所以我会在这里发布我的笔记:

我经常混淆的一件事是语法;因此下面有一个 bash 测试脚本,它创建一些临时目录,然后启动一个临时 ftp 服务器,并将 rsync(在纯本地文件模式下,因为它不支持 ftp)与 lftpftpsync 进行比较。

问题是 - 您可以使用 rsync /path/to/local /path/to/remote/,rsync 将自动确定您想要在 remote 下创建一个名为 local 的子目录;但是,对于 lftpftpsync,您必须手动指定目标目录,例如 ... /path/to/local /path/to/remote/local(如果不存在,则会创建该目录)。

你可以在如何暂时运行FTP服务器?- Ask Ubuntu中找到ftpserver-cli.py;而ftpsync在这里:FTPsync(但请注意它有缺陷;另请参见搜索/过滤FTP远程文件名-Unix和Linux Stack Exchange);

这是puttest.sh脚本的缩短输出,显示了不同情况下递归放置的行为:

$ bash puttest.sh 
Recreate directories; populate loctest, keep srvtest empty:
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
/tmp/loctest
├── .git
│   └── tempa2.txt
└── tempa1.txt

*NOTE, rsync can automatically figure out parent dir:
+ rsync -a --exclude '*.git*' /tmp/loctest /tmp/srvtest/
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── loctest
    └── tempa1.txt
/tmp/loctest
├── .git
│   └── tempa2.txt
└── tempa1.txt
cleanup:
+ rm -rf /tmp/srvtest/loctest

Start a temporary ftp server:
+ sudo bash -c 'python /path/to/pyftpdlib/ftpserver-cli.py --username=user --password=12345 --directory=/tmp/srvtest &'
+ sleep 1
Using: user: user pass: 12345 port: 21 dir: /tmp/srvtest
[I 14-03-02 23:24:01] >>> starting FTP server on 127.0.0.1:21, pid=21549 <<<
[I 14-03-02 23:24:01] poller: <class 'pyftpdlib.ioloop.Epoll'>
[I 14-03-02 23:24:01] masquerade (NAT) address: None
[I 14-03-02 23:24:01] passive ports: None
[I 14-03-02 23:24:01] use sendfile(2): False
test with lftp:

*NOTE, lftp syncs *contents* of local dir (rsync-like syntax doesn't create target dir):
+ lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest / ; exit' -u user,12345 127.0.0.1
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── tempa1.txt
/tmp/loctest
├── .git
│   └── tempa2.txt
└── tempa1.txt
cleanup:
+ rm -rf /tmp/srvtest/tempa1.txt

*NOTE, specify lftp target dir explicitly (will be autocreated):
+ lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest /loctest ; exit' -u user,12345 127.0.0.1
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── loctest
    └── tempa1.txt
/tmp/loctest
├── .git
│   └── tempa2.txt
└── tempa1.txt
cleanup:
+ sudo rm -rf /tmp/srvtest/loctest

*NOTE, ftpsync syncs *contents* of local dir (rsync-like syntax doesn't create target dir); also info mode -i is buggy (it puts, although it shouldn't):

*NOTE, ftpsync --ignoremask is for older unused code; use --exclude instead (but it is buggy; need to change  in source)
+ /path/to/ftpsync/ftpsync -i -d '--exclude=.*\.git.*' /tmp/loctest ftp://user:12345@127.0.0.1/
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── tempa1.txt
/tmp/loctest
├── .git
│   └── tempa2.txt
└── tempa1.txt
cleanup:
+ sudo rm -rf /tmp/srvtest/tempa1.txt

*NOTE, specify ftpsync target dir explicitly (will be autocreated):
+ /path/to/ftpsync/ftpsync -i -d '--exclude=.*\.git.*' /tmp/loctest ftp://user:12345@127.0.0.1/loctest
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── loctest
    └── tempa1.txt
/tmp/loctest
├── .git
│   └── tempa2.txt
└── tempa1.txt
cleanup:
+ sudo rm -rf /tmp/srvtest/loctest
+ sudo pkill -f ftpserver-cli.py

这里是 puttest.sh 脚本:

#!/usr/bin/env bash
set -x

# change these to match your installations:
FTPSRVCLIPATH="/path/to/pyftpdlib"
FTPSYNCPATH="/path/to/ftpsync"

{ echo "Recreate directories; populate loctest, keep srvtest empty:"; } 2>/dev/null

sudo rm -rf /tmp/srvtest /tmp/loctest

mkdir /tmp/srvtest

mkdir -p /tmp/loctest/.git
echo aaa > /tmp/loctest/tempa1.txt
echo aaa > /tmp/loctest/.git/tempa2.txt

{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest

{ echo -e "\n*NOTE, rsync can automatically figure out parent dir:"; } 2>/dev/null

rsync -a --exclude '*.git*' /tmp/loctest /tmp/srvtest/

{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest

{ echo "cleanup:"; } 2>/dev/null
rm -rf /tmp/srvtest/*

{ echo -e "\nStart a temporary ftp server:"; } 2>/dev/null

# https://askubuntu.com/questions/17084/how-do-i-temporarily-run-an-ftp-server

sudo bash -c "python $FTPSRVCLIPATH/ftpserver-cli.py --username=user --password=12345 --directory=/tmp/srvtest &"
sleep 1

{ echo "test with lftp:"; } 2>/dev/null
# see http://russbrooks.com/2010/11/19/lftp-cheetsheet
# The -R switch means "reverse mirror" which means "put" [upload].
{ echo -e "\n*NOTE, lftp syncs *contents* of local dir (rsync-like syntax doesn't create target dir):"; } 2>/dev/null

lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest / ; exit' -u user,12345 127.0.0.1

{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest

{ echo "cleanup:"; } 2>/dev/null
rm -rf /tmp/srvtest/*

{ echo -e "\n*NOTE, specify lftp target dir explicitly (will be autocreated):"; } 2>/dev/null

lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest /loctest ; exit' -u user,12345 127.0.0.1

{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest

{ echo "cleanup:"; } 2>/dev/null
sudo rm -rf /tmp/srvtest/*

{ echo -e "\n*NOTE, ftpsync syncs *contents* of local dir (rsync-like syntax doesn't create target dir); also info mode -i is buggy (it puts, although it shouldn't):"; } 2>/dev/null
{ echo -e "\n*NOTE, ftpsync --ignoremask is for older unused code; use --exclude instead (but it is buggy; need to change `  'exclude=s' => \$opt::exclude,` in source)"; } 2>/dev/null

$FTPSYNCPATH/ftpsync -i -d --exclude='.*\.git.*' /tmp/loctest ftp://user:12345@127.0.0.1/

{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest

{ echo "cleanup:"; } 2>/dev/null
sudo rm -rf /tmp/srvtest/*

{ echo -e "\n*NOTE, specify ftpsync target dir explicitly (will be autocreated):"; } 2>/dev/null

$FTPSYNCPATH/ftpsync -i -d --exclude='.*\.git.*' /tmp/loctest ftp://user:12345@127.0.0.1/loctest

{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest

{ echo "cleanup:"; } 2>/dev/null
sudo rm -rf /tmp/srvtest/*


sudo pkill -f ftpserver-cli.py

{ set +x; } 2>/dev/null

0

没有提到ncftp吗?

在Ubuntu中,使用sudo apt install ncftp安装。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接