参考 https://www.cnblogs.com/mingforyou/p/4103022.html
一、安装及配置
1、直接使用yum安装
yum -y install vsftpd
2、配置文件说明
/etc/vsftpd/vsftpd.conf 是 vsftpd 的核心配置文件。
/etc/vsftpd/ftpusers 是黑名单文件,此文件里的用户不允许访问 FTP 服务器。
/etc/vsftpd/user_list 是白名单文件,此文件里的用户允许访问 FTP 服务器。
3、修改配置文件
vim /etc/vsftp/vsftp.conf
anonymous_enable=NO #禁止匿名登录
local_enable=YES #允许本地用户登录FTP服务器
local_root=/data/ftp #设置本地用户登录后所在目录
chroot_local_user=YES #所有的用户有锁定在这个根目录,登陆ftp后只能在local_root设置的目录下
chroot_list_enable=YES #开启,则chroot_list_file下的用户不受限制,可以到任意的目录下
chroot_list_file=/etc/vsftpd/chroot_list #在这个文件里写入不受限制的用户名
allow_writeable_chroot=YES #开启write的权限
4、重启ftp
systemctl enable vsftpd
systemctl restart vsftpd
5、登陆ftp
可以直接使用ftp ftp服务器ip
命令,也可以先使用ftp命令进入ftp命令行,在使用open ftp服务器ip
命令
方法一
ftp 10.0.0.106
方法二
ftp
open 10.0.0.106
二、常用命令
1、ftp的get命令和mget命令有何不同?
get一次只下载一个文件;mget一次可以下载多个文件,而且支持通配符,需要注意的是在mget的时侯,需要对每一个文件都选择y/n,如果想不交互的下载全部的文件,可以先用prompt命令关掉交互方式(关闭:prompt off;打开:prompt on)。
二、FTP使用什么命令来定位服务器与本地硬盘的路径?
ftp中用lcd切换本地路径,用cd切换远程服务器的路径。常用到的命令如下:
cd目录名(进入服务器目录) lcd目录名(进入本机目录)
cd \(退到服务器根目录) lcd \(退到本机根目录)
cd …(退回到上一级目录) lcd …(退回到上一级目录)
三、!命令有何作用?
执行本地shell命令,如:!dir(显示本机当亲目录内容),如果不加!如:dir(显示服务器当前目录内容)
四、ftp命令支持“含有空格”的文件夹/文件名吗?
支持,只要在引用时加上双引号“”即可!
五、下面是命令行方式使用FTP的实战练习
假设有一ftp服务器:ftp.test.com,用户名:username,密码:user1234。在本地电脑D:盘创建一个文件夹“qint”。将要上传的文件复制到D:\qint里。通过FTP命令将文件从本地上传,从服务器下载的步骤如下:
1、“开始”→“运行”→输入“FTP”
2、open ftp.test.com
注意:这一步可以与第一步合并,在“运行”里直接输入:ftp ftp.test.com。如果你的FTP服务器不是用的21默认端口,假如端口是2121,那么此步的命令应在后面空格加2121,即“open ftp.test.com
3、username
注意:提示你输入用户名
4、user1234
注意:提示你输入密码,密码不回显,打完密码后回车即可。如果你的密码输入错误,将不会提示你重新输入,这时你要键入“user”命令,将会出现第三步,你可以重新输入用户名和密码。
5、dir
注意:你成功登陆后就可以用dir查看命令查看FTP服务器中的文件及目录,用ls命令只可以查看文件。
6、mkdir qint
注意:在FTP服务器上根目录下建立qint目录
7、cd qint
注意:进入目录qint,用“cd 你的目录名”可以进入当前目录的下一级目录,这跟DOS一样。
8、bin
注意:采用二进制传输。如果你要上传下载,这一步很重要,不先执行这个命令,上传下载会很慢。大多数系统(包括UNIX系统)只有两种模式:文本模式和二进制模式。文本传输器使用ASCII字符,并由回车键和换行符分开,而二进制不用转换或格式化就可传字符,二进制模式比文本模式更快,并且可以传输所有ASCII值,所以系统管理员一般将FTP设置成二进制模式。一般来说,我们最好都用binary方式,这样可以保证不出错。
9、lcd d:\qint
注意:定位本地默认文件夹,在前面已事先在D:盘创建
10、!dir
注意:查看本地文件夹中的文件及目录
11、put i001.jpg
注意:将当前目录(d:\qint)中的文件i001.jpg上传到FTP服务器默认目录。可以用“mput .”将所有文件上传到FTP服务器上。
12、get d123.jpg
注意:将FTP服务器默认目录中的文件d123.jpg下载到当前目录下(d:\qint)。可以用“mget .”将所有文件下载到d:\qint
13、delete .
注意:删除服务器对应目录qint中的所有文件。
14、cd …
注意:返回至上一级目录,即根目录。返回上一级目录用“cd …”要注意,中间有空格。返回根目录用“cd \”。
15、mrdir qint
注意:删除目录qint。删除目录,在此目录下不能有文件及目录,不然将无法删除。
16、bye
注意:退出FTP服务器。
上传下载时特别要注意服务器及本地电脑的当前目录,文件是从哪里到哪里的问题。查看FTP服务器的当前目录命令为pwd,可以用cd命令定位服务器的目录。可以用lcd命令定位本地电脑的目录。
以上实例应用到了采用FTP命令行方式上传下载的最常用命令,你还可以用命令“?”查看更多的命令。
FTP命令是Internet用户使用最频繁的命令之一,不论是在DOS还是UNIX操作系统下使用FTP,都会遇到大量的FTP内部命令。熟悉并灵活应用FTP的内部命令,可以大大方便使用者,并收到事半功倍之效。
FTP的命令行格式为:ftp -v -d -i -n -g [主机名],其中
-v显示远程服务器的所有响应信息;
-n限制ftp的自动登录,即不使用;
.n etrc文件;
-d使用调试方式;
-g取消全局文件名。
ftp使用的内部命令如下(中括号表示可选项):
1.![cmd[args]]:在本地机中执行交互shell,exit回到ftp环境,如:!ls*.zip.
2.$ macro-ame[args]:执行宏定义macro-name.
3.account[password]:提供登录远程系统成功后访问系统资源所需的补充口令。
4.append local-file[remote-file]:将本地文件追加到远程系统主机,若未指定远程系统文件名,则使用本地文件名。
5.ascii:使用ascii类型传输方式。
6.bell:每个命令执行完毕后计算机响铃一次。
7.bin:使用二进制文件传输方式。
8.bye:退出ftp会话过程。
9.case:在使用mget时,将远程主机文件名中的大写转为小写字母。
10.cd remote-dir:进入远程主机目录。
11.cdup:进入远程主机目录的父目录。
12.chmod mode file-name:将远程主机文件file-name的存取方式设置为mode,如:chmod 777 a.out。
13.close:中断与远程服务器的ftp会话(与open对应)。
14.cr:使用asscii方式传输文件时,将回车换行转换为回行。
15.delete remote-file:删除远程主机文件。
16.debug[debug-value]:设置调试方式,显示发送至远程主机的每条命令,如:deb up 3,若设为0,表示取消debug。
17.dir[remote-dir][local-file]:显示远程主机目录,并将结果存入本地文件local-file。
18.disconnection:同close。
19.form format:将文件传输方式设置为format,缺省为file方式。
20.get remote-file[local-file]:将远程主机的文件remote-file传至本地硬盘的local-file。
21.glob:设置mdelete,mget,mput的文件名扩展,缺省时不扩展文件名,同命令行的-g参数。
22.hash:每传输1024字节,显示一个hash符号(#)。
23.help[cmd]:显示ftp内部命令cmd的帮助信息,如:help get。
24.idle[seconds]:将远程服务器的休眠计时器设为[seconds]秒。
25.image:设置二进制传输方式(同binary)。
26.lcd[dir]:将本地工作目录切换至dir。
27.ls[remote-dir][local-file]:显示远程目录remote-dir,并存入本地文件local-file。
28.macdef macro-name:定义一个宏,遇到macdef下的空行时,宏定义结束。
29.mdelete[remote-file]:删除远程主机文件。
30.mdir remote-files local-file:与dir类似,但可指定多个远程文件,如:mdir *.o.*.zipoutfile
31.mget remote-files:传输多个远程文件。
32.mkdir dir-name:在远程主机中建一目录。
33.mls remote-file local-file:同nlist,但可指定多个文件名。
34.mode[modename]:将文件传输方式设置为modename,缺省为stream方式。
35.modtime file-name:显示远程主机文件的最后修改时间。
36.mput local-file:将多个文件传输至远程主机。
37.newer file-name:如果远程机中file-name的修改时间比本地硬盘同名文件的时间更近,则重传该文件。
38.nlist[remote-dir][local-file]:显示远程主机目录的文件清单,并存入本地硬盘的local-file。
39.nmap[inpattern outpattern]:设置文件名映射机制,使得文件传输时,文件中的某些字符相互转换,如:nmap $1.$2.$3[$1,$2].[$2,$3],则传输文件a1.a2.a3时,文件名变为a1,a2。该命令特别适用于远程主机为非UNIX机的情况。
40.ntrans[inchars[outchars]]:设置文件名字符的翻译机制,如ntrans 1R,则文件名LLL将变为RRR。
41.open host[port]:建立指定ftp服务器连接,可指定连接端口。
42.passive:进入被动传输方式。
43.prompt:设置多个文件传输时的交互提示。
44.proxy ftp-cmd:在次要控制连接中,执行一条ftp命令,该命令允许连接两个ftp服务器,以在两个服务器间传输文件。第一条ftp命令必须为open,以首先建立两个服务器间的连接。
45.put local-file[remote-file]:将本地文件local-file传送至远程主机。
46.pwd:显示远程主机的当前工作目录。
47.quit:同bye,退出ftp会话。
48.quote arg1,arg2...:将参数逐字发至远程ftp服务器,如:quote syst.
49.recv remote-file[local-file]:同get。
50.reget remote-file[local-file]:类似于get,但若local-file存在,则从上次传输中断处续传。
51.rhelp[cmd-name]:请求获得远程主机的帮助。
52.rstatus[file-name]:若未指定文件名,则显示远程主机的状态,否则显示文件状态。
53.rename[from][to]:更改远程主机文件名。
54.reset:清除回答队列。
55.restart marker:从指定的标志marker处,重新开始get或put,如:restart 130。
56.rmdir dir-name:删除远程主机目录。
57.runique:设置文件名唯一性存储,若文件存在,则在原文件后加后缀..1,.2等。
58.send local-file[remote-file]:同put。
59.sendport:设置PORT命令的使用。
60.site arg1,arg2...:将参数作为SITE命令逐字发送至远程ftp主机。
61.size file-name:显示远程主机文件大小,如:site idle 7200。
62.status:显示当前ftp状态。
63.struct[struct-name]:将文件传输结构设置为struct-name,缺省时使用stream结构。
64.sunique:将远程主机文件名存储设置为唯一(与runique对应)。
65.system:显示远程主机的操作系统类型。
66.tenex:将文件传输类型设置为TENEX机的所需的类型。
67.tick:设置传输时的字节计数器。
68.trace:设置包跟踪。
69.type[type-name]:设置文件传输类型为type-name,缺省为ascii,如:type binary,设置二进制传输方式。
70.umask[newmask]:将远程服务器的缺省umask设置为newmask,如:umask 3。
71.user user-name[password][account]:向远程主机表明自己的身份,需要口令时,必须输入口令,如:user anonymous my@email。
72.verbose:同命令行的-v参数,即设置详尽报告方式,ftp服务器的所有响应都将显示给用户,缺省为on.
73.?[cmd]:同help。
假设FTP地址为“ 61.129.83.39”(大家试验的时候不要以这个FTP去试,应该可能密码要改掉。)
1:“开始”-“运行”-输入“FTP”进去cmd界面
2.open 61.129.83.39
如果你的FTP服务器不是用的21默认端口,假如端口是9900,那么此步的命令应在后面空格加9900,即为 open 61.129.83.39 9900
3:它会提示输入用户名 username
4: 它会提示你输入密码:password
注意密码不显示出来,打完密码后回车即可。如果你的密码输入错误,将不会提示你重新输入,这时你只要键入“user”命令,你就可以重新输入用户名和密码。
5:成功登陆后就可以用dir查看命令查看FTP服务器中的文件及目录,用ls命令只可以查看文件。
6:使用cd 命令转目录,delete删文件,用法跟DOS差不多。呵呵!!
7:lcd d:dianying 定位本地默认文件夹(本人理解这里的L是local当地英文的缩写,很好理解和记忆)
8:下面就是上传和下载文件的命令了,上传用put 文件名.下载用get 文件名
当然下载到当前目录了,就是上面定义的"d:dianying"
9:最后就退出了
用bye命令。
ftp [-v][-d][-i][-n][-g][-s:FileName][-a][-w:WindowSize][-A][Host]
参数
-v
禁止显示 FTP 服务器响应。
/d
启用调试、显示在 FTP 客户端和 FTP 服务器之间传递的所有命令。
-i
传送多个文件时禁用交互提示。
-n
在建立初始连接后禁止自动登录功能。
-g
禁用文件名组合。Glob 允许使用星号 (*) 和问号 (?) 作为本地文件和路径名
的通配符字符。
-s:filename
指定包含 ftp 命令的文本文件。这些命令在启动 ftp 后自动运行。该参数不
允许带有空格。使用该参数而不是重定向 (<)。
-a
指定绑定 FTP 数据连接时可以使用任何本地接口。
-w:windowsize
指定传输缓冲的大小。默认窗口大小为 4096 字节。
-A
匿名登录到 FTP 服务器。
Host
指定要连接的计算机名、IP 地址或 FTP 服务器的 IPv6 地址。如果指定了主
机名或地址,则其必须是命令行的最后一个参数。
/?
在命令提示符下显示帮助。
常用命令:
1. open:与ftp服务器相连接;
2. send(put):上传文件;
3. get:下载文件;
4. mget:下载多个文件;
5. cd:切换目录;
三、python操作ftp
转载https://blog.csdn.net/qq_26775359/article/details/93500728
http://blog.csdn.net/ouyang_peng/article/details/79271113
1、简介方法
# coding:utf8
from ftplib import FTP
def upload(f, remote_path, local_path):
fp = open(local_path, "rb")
buf_size = 4096
f.storbinary("STOR {}".format(remote_path), fp, buf_size)
fp.close()
def download(f, remote_path, local_path):
fp = open(local_path, "wb")
buf_size = 1024
f.retrbinary('RETR {}'.format(remote_path), fp.write, buf_size)
fp.close()
if __name__ == "__main__":
ftp = FTP()
ftp.connect("192.168.169.3", 21) # 第一个参数可以是ftp服务器的ip或者域名,第二个参数为ftp服务器的连接端口,默认为21
ftp.login('user', 'passwd') # 匿名登录直接使用ftp.login()
ftp.set_pasv(False)
ftp.cwd("/ftp/tmp") # 切换到tmp目录
upload(ftp, "a.txt", "ftp_a.txt") # 将当前目录下的a.txt文件上传到ftp服务器的tmp目录,命名为ftp_a.txt
#download(ftp, "ftp_a.txt", "b.txt") # 将ftp服务器tmp目录下的ftp_a.txt文件下载到当前目录,命名为b.txt
print('yes ok!')
ftp.quit()
2、方法类
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from ftplib import FTP
import os
import sys
import time
import socket
class MyFTP:
"""
ftp自动下载、自动上传脚本,可以递归目录操作
作者:欧阳鹏
博客地址:http://blog.csdn.net/ouyang_peng/article/details/79271113
"""
def __init__(self, host, port=21):
""" 初始化 FTP 客户端
参数:
host:ip地址
port:端口号
"""
# print("__init__()---> host = %s ,port = %s" % (host, port))
self.host = host
self.port = port
self.ftp = FTP()
# 重新设置下编码方式
self.ftp.encoding = 'gbk'
self.log_file = open("log.txt", "a")
self.file_list = []
def login(self, username, password):
""" 初始化 FTP 客户端
参数:
username: 用户名
password: 密码
"""
try:
timeout = 60
socket.setdefaulttimeout(timeout)
# 0主动模式 1 #被动模式
self.ftp.set_pasv(False)
# 打开调试级别2,显示详细信息
# self.ftp.set_debuglevel(2)
self.debug_print('开始尝试连接到 %s' % self.host)
self.ftp.connect(self.host, self.port)
self.debug_print('成功连接到 %s' % self.host)
self.debug_print('开始尝试登录到 %s' % self.host)
self.ftp.login(username, password)
self.debug_print('成功登录到 %s' % self.host)
self.debug_print(self.ftp.welcome)
except Exception as err:
self.deal_error("FTP 连接或登录失败 ,错误描述为:%s" % err)
pass
def is_same_size(self, local_file, remote_file):
"""判断远程文件和本地文件大小是否一致
参数:
local_file: 本地文件
remote_file: 远程文件
"""
try:
remote_file_size = self.ftp.size(remote_file)
except Exception as err:
#self.debug_print("is_same_size() 错误描述为:%s" % err)
remote_file_size = -1
try:
local_file_size = os.path.getsize(local_file)
except Exception as err:
# self.debug_print("is_same_size() 错误描述为:%s" % err)
local_file_size = -1
self.debug_print('local_file_size:%d , remote_file_size:%d' % (local_file_size, remote_file_size))
if remote_file_size == local_file_size:
return 1
else:
return 0
def download_file(self, local_file, remote_file):
"""从ftp下载文件
参数:
local_file: 本地文件
remote_file: 远程文件
"""
self.debug_print("download_file()---> local_path = %s ,remote_path = %s" % (local_file, remote_file))
if self.is_same_size(local_file, remote_file):
self.debug_print('%s 文件大小相同,无需下载' % local_file)
return
else:
try:
self.debug_print('>>>>>>>>>>>>下载文件 %s ... ...' % local_file)
buf_size = 1024
file_handler = open(local_file, 'wb')
self.ftp.retrbinary('RETR %s' % remote_file, file_handler.write, buf_size)
file_handler.close()
except Exception as err:
self.debug_print('下载文件出错,出现异常:%s ' % err)
return
def download_file_tree(self, local_path, remote_path):
"""从远程目录下载多个文件到本地目录
参数:
local_path: 本地路径
remote_path: 远程路径
"""
print("download_file_tree()---> local_path = %s ,remote_path = %s" % (local_path, remote_path))
try:
self.ftp.cwd(remote_path)
except Exception as err:
self.debug_print('远程目录%s不存在,继续...' % remote_path + " ,具体错误描述为:%s" % err)
return
if not os.path.isdir(local_path):
self.debug_print('本地目录%s不存在,先创建本地目录' % local_path)
os.makedirs(local_path)
self.debug_print('切换至目录: %s' % self.ftp.pwd())
self.file_list = []
# 方法回调
self.ftp.dir(self.get_file_list)
remote_names = self.file_list
self.debug_print('远程目录 列表: %s' % remote_names)
for item in remote_names:
file_type = item[0]
file_name = item[1]
local = os.path.join(local_path, file_name)
if file_type == 'd':
print("download_file_tree()---> 下载目录: %s" % file_name)
self.download_file_tree(local, file_name)
elif file_type == '-':
print("download_file()---> 下载文件: %s" % file_name)
self.download_file(local, file_name)
self.ftp.cwd("..")
self.debug_print('返回上层目录 %s' % self.ftp.pwd())
return True
def upload_file(self, local_file, remote_file):
"""从本地上传文件到ftp
参数:
local_path: 本地文件
remote_path: 远程文件
"""
if not os.path.isfile(local_file):
self.debug_print('%s 不存在' % local_file)
return
if self.is_same_size(local_file, remote_file):
self.debug_print('跳过相等的文件: %s' % local_file)
return
buf_size = 1024
file_handler = open(local_file, 'rb')
self.ftp.storbinary('STOR %s' % remote_file, file_handler, buf_size)
file_handler.close()
self.debug_print('上传: %s' % local_file + "成功!")
def upload_file_tree(self, local_path, remote_path):
"""从本地上传目录下多个文件到ftp
参数:
local_path: 本地路径
remote_path: 远程路径
"""
if not os.path.isdir(local_path):
self.debug_print('本地目录 %s 不存在' % local_path)
return
"""
创建服务器目录
"""
try:
self.ftp.cwd(remote_path) # 切换工作路径
except Exception as e:
base_dir, part_path = self.ftp.pwd(), remote_path.split('/')
for p in part_path[1:-1]:
base_dir = base_dir + p + '/' # 拼接子目录
try:
self.ftp.cwd(base_dir) # 切换到子目录, 不存在则异常
except Exception as e:
print('INFO:', e)
self.ftp.mkd(base_dir) # 不存在创建当前子目录
#self.ftp.cwd(remote_path)
self.debug_print('切换至远程目录: %s' % self.ftp.pwd())
local_name_list = os.listdir(local_path)
self.debug_print('本地目录list: %s' % local_name_list)
#self.debug_print('判断是否有服务器目录: %s' % os.path.isdir())
for local_name in local_name_list:
src = os.path.join(local_path, local_name)
print("src路径=========="+src)
if os.path.isdir(src):
try:
self.ftp.mkd(local_name)
except Exception as err:
self.debug_print("目录已存在 %s ,具体错误描述为:%s" % (local_name, err))
self.debug_print("upload_file_tree()---> 上传目录: %s" % local_name)
self.debug_print("upload_file_tree()---> 上传src目录: %s" % src)
self.upload_file_tree(src, local_name)
else:
self.debug_print("upload_file_tree()---> 上传文件: %s" % local_name)
self.upload_file(src, local_name)
self.ftp.cwd("..")
def close(self):
""" 退出ftp
"""
self.debug_print("close()---> FTP退出")
self.ftp.quit()
self.log_file.close()
def debug_print(self, s):
""" 打印日志
"""
self.write_log(s)
def deal_error(self, e):
""" 处理错误异常
参数:
e:异常
"""
log_str = '发生错误: %s' % e
self.write_log(log_str)
sys.exit()
def write_log(self, log_str):
""" 记录日志
参数:
log_str:日志
"""
time_now = time.localtime()
date_now = time.strftime('%Y-%m-%d', time_now)
format_log_str = "%s ---> %s \n " % (date_now, log_str)
print(format_log_str)
self.log_file.write(format_log_str)
def get_file_list(self, line):
""" 获取文件列表
参数:
line:
"""
file_arr = self.get_file_name(line)
# 去除 . 和 ..
if file_arr[1] not in ['.', '..']:
self.file_list.append(file_arr)
def get_file_name(self, line):
""" 获取文件名
参数:
line:
"""
pos = line.rfind(':')
while (line[pos] != ' '):
pos += 1
while (line[pos] == ' '):
pos += 1
file_arr = [line[0], line[pos:]]
return file_arr
if __name__ == "__main__":
my_ftp = MyFTP("10.0.0.106")
my_ftp.login("wangxiaoyu", "123456")
# 下载单个文件
#my_ftp.download_file("/home/BG_2019_05_22_16_04_54_Camera6-0.mp4", "/BG_2019_05_22_16_04_54_Camera6-0.mp4") #FTP服务器目录 本地目录
# 下载目录
# my_ftp.download_file_tree("G:/ftp_test/", "App/AutoUpload/ouyangpeng/I12/")
# 上传单个文件
my_ftp.upload_file("puttest.txt", "puttest.txt")
# 上传目录
#my_ftp.upload_file_tree("puttest.txt", "puttest.txt")
my_ftp.close()