python ftplib ftp.rename() 在某些服务器中抛出错误
python ftplib ftp.rename() throwing error in some servers
刚开始使用 FTP 和 SFTP 编写一些 python 脚本。 SFTP 似乎在所有情况下都能正常工作,但是当脚本尝试使用 FTP 重命名文件时,它在某些服务器上工作并且在某些服务器上抛出错误。我目前正在研究 python 3.9.6 并分享下面的代码示例。
ftp = FTP(host='ip', user='user', passwd='password')
if ftp.size("/path/to/some/directory/filename.txt") is not None:
print("{} is a file".format("/path/to/some/directory/filename.txt"))
else:
print("It's NOT a file!")
try:
print("Downloading file")
with open("/path/to/some/directory/filename.txt", "wb") as file:
ftp.retrbinary("RETR %s" %file_path + file_name, file.write)
file.close()
print("Download completed!")
try:
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now()).replace(" ", "_") + ".txt")
print("File renamed.")
except:
traceback.print_exc()
except:
print("Excetion while Downloading file!")
traceback.print_exc()
ftp.quit()
我已经在 3 个不同的服务器上测试了这段代码。在前 2 个中,我取得了成功(即文件已正确移动)。对于最后一个,我收到以下错误
Traceback (most recent call last):
File "/path/to/script/ftp.py", line 37, in <module>
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now()).replace(" ", "_") + ".txt")
File "/usr/local/lib/python3.9/ftplib.py", line 604, in rename
return self.voidcmd('RNTO ' + toname)
File "/usr/local/lib/python3.9/ftplib.py", line 286, in voidcmd
return self.voidresp()
File "/usr/local/lib/python3.9/ftplib.py", line 259, in voidresp
resp = self.getresp()
File "/usr/local/lib/python3.9/ftplib.py", line 252, in getresp
raise error_temp(resp)
ftplib.error_temp: 450 Internal error renaming the file
这只发生在我尝试脚本的最后一个服务器上。我注意到的另一件事是,当我以 FTP 用户身份登录该服务器并尝试手动重命名文件时,重命名命令起作用。这意味着 FTP 用户拥有文件和备份路径的权限。
添加错误和成功案例的 debuglevel(2) 日志。 注意:这些日志来自具有相同脚本的 2 个不同服务器。为了找出问题所在,我只使用了脚本中的重命名代码。
来自脚本 运行s 成功 的服务器的日志 - vsFTPd 3.0.2
Renaming file
cmd 'RNFR /path/to/some/directory/filename.txt'
put 'RNFR /path/to/some/directory/filename.txt\r\n'
get '350 Ready for RNTO.\n'
resp '350 Ready for RNTO.'
cmd 'RNTO /path/to/backup/filename_2022-06-01_10:31:45.765201.txt'
put 'RNTO /path/to/backup/filename_2022-06-01_10:31:45.765201.txt\r\n'
get '250 Rename successful.\n'
resp '250 Rename successful.'
File renamed.
来自脚本失败的服务器的日志 - FileZilla Server 0.9.60 beta
Renaming file
cmd 'RNFR /path/to/some/directory/sample_tst.txt'
put 'RNFR /path/to/some/directory/sample_tst.txt\r\n'
get '350 File exists, ready for destination name.\n'
resp '350 File exists, ready for destination name.'
cmd 'RNTO /path/to/backup/filename_2022-06-01_10:16:45.088433.txt'
put 'RNTO /path/to/backup/filename_2022-06-01_10:16:45.088433.txt\r\n'
get '450 Internal error renaming the file\n'
resp '450 Internal error renaming the file'
Excetion while renaming file: <class 'ftplib.error_temp'>
Traceback (most recent call last):
File "/opt/APPS/SCRIPT/ftp.py", line 36, in <module>
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now()).replace(" ", "_") + ".txt")
File "/usr/local/lib/python3.9/ftplib.py", line 604, in rename
return self.voidcmd('RNTO ' + toname)
File "/usr/local/lib/python3.9/ftplib.py", line 286, in voidcmd
return self.voidresp()
File "/usr/local/lib/python3.9/ftplib.py", line 259, in voidresp
resp = self.getresp()
File "/usr/local/lib/python3.9/ftplib.py", line 252, in getresp
raise error_temp(resp)
ftplib.error_temp: 450 Internal error renaming the file
这是我尝试在故障服务器中手动执行时的调试级别日志。
ftp> debug 2
Debugging on (debug=2).
ftp>
ftp>
ftp> rename /path/to/some/directory/filename.txt /path/to/backup/filename_2022-06-01_12:16.txt
---> RNFR /path/to/some/directory/filename.txt
350 File exists, ready for destination name.
---> RNTO /path/to/backup/filename_2022-06-01_12:16.txt
250 file renamed successfully
ftp>
以上是我以 FTP 用户身份登录时尝试使用重命名命令移动它的屏幕截图。
过去几天我一直在研究这个问题,但一无所获。如果有人能帮助我解决这个问题,我将不胜感激。
两台服务器 运行 Red Hat Enterprise Linux
提前致谢。
问题出在文件名上。不支持完整的冒号。因此,我没有附加完整的时间戳,而是将其格式化如下。
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now().strftime("%Y-%m-%d %H%M%S")).replace(" ", "_") + ".txt")
现在可以使用了。
谢谢@Martin 指出错误。
刚开始使用 FTP 和 SFTP 编写一些 python 脚本。 SFTP 似乎在所有情况下都能正常工作,但是当脚本尝试使用 FTP 重命名文件时,它在某些服务器上工作并且在某些服务器上抛出错误。我目前正在研究 python 3.9.6 并分享下面的代码示例。
ftp = FTP(host='ip', user='user', passwd='password')
if ftp.size("/path/to/some/directory/filename.txt") is not None:
print("{} is a file".format("/path/to/some/directory/filename.txt"))
else:
print("It's NOT a file!")
try:
print("Downloading file")
with open("/path/to/some/directory/filename.txt", "wb") as file:
ftp.retrbinary("RETR %s" %file_path + file_name, file.write)
file.close()
print("Download completed!")
try:
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now()).replace(" ", "_") + ".txt")
print("File renamed.")
except:
traceback.print_exc()
except:
print("Excetion while Downloading file!")
traceback.print_exc()
ftp.quit()
我已经在 3 个不同的服务器上测试了这段代码。在前 2 个中,我取得了成功(即文件已正确移动)。对于最后一个,我收到以下错误
Traceback (most recent call last):
File "/path/to/script/ftp.py", line 37, in <module>
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now()).replace(" ", "_") + ".txt")
File "/usr/local/lib/python3.9/ftplib.py", line 604, in rename
return self.voidcmd('RNTO ' + toname)
File "/usr/local/lib/python3.9/ftplib.py", line 286, in voidcmd
return self.voidresp()
File "/usr/local/lib/python3.9/ftplib.py", line 259, in voidresp
resp = self.getresp()
File "/usr/local/lib/python3.9/ftplib.py", line 252, in getresp
raise error_temp(resp)
ftplib.error_temp: 450 Internal error renaming the file
这只发生在我尝试脚本的最后一个服务器上。我注意到的另一件事是,当我以 FTP 用户身份登录该服务器并尝试手动重命名文件时,重命名命令起作用。这意味着 FTP 用户拥有文件和备份路径的权限。
添加错误和成功案例的 debuglevel(2) 日志。 注意:这些日志来自具有相同脚本的 2 个不同服务器。为了找出问题所在,我只使用了脚本中的重命名代码。
来自脚本 运行s 成功 的服务器的日志 - vsFTPd 3.0.2
Renaming file
cmd 'RNFR /path/to/some/directory/filename.txt'
put 'RNFR /path/to/some/directory/filename.txt\r\n'
get '350 Ready for RNTO.\n'
resp '350 Ready for RNTO.'
cmd 'RNTO /path/to/backup/filename_2022-06-01_10:31:45.765201.txt'
put 'RNTO /path/to/backup/filename_2022-06-01_10:31:45.765201.txt\r\n'
get '250 Rename successful.\n'
resp '250 Rename successful.'
File renamed.
来自脚本失败的服务器的日志 - FileZilla Server 0.9.60 beta
Renaming file
cmd 'RNFR /path/to/some/directory/sample_tst.txt'
put 'RNFR /path/to/some/directory/sample_tst.txt\r\n'
get '350 File exists, ready for destination name.\n'
resp '350 File exists, ready for destination name.'
cmd 'RNTO /path/to/backup/filename_2022-06-01_10:16:45.088433.txt'
put 'RNTO /path/to/backup/filename_2022-06-01_10:16:45.088433.txt\r\n'
get '450 Internal error renaming the file\n'
resp '450 Internal error renaming the file'
Excetion while renaming file: <class 'ftplib.error_temp'>
Traceback (most recent call last):
File "/opt/APPS/SCRIPT/ftp.py", line 36, in <module>
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now()).replace(" ", "_") + ".txt")
File "/usr/local/lib/python3.9/ftplib.py", line 604, in rename
return self.voidcmd('RNTO ' + toname)
File "/usr/local/lib/python3.9/ftplib.py", line 286, in voidcmd
return self.voidresp()
File "/usr/local/lib/python3.9/ftplib.py", line 259, in voidresp
resp = self.getresp()
File "/usr/local/lib/python3.9/ftplib.py", line 252, in getresp
raise error_temp(resp)
ftplib.error_temp: 450 Internal error renaming the file
这是我尝试在故障服务器中手动执行时的调试级别日志。
ftp> debug 2
Debugging on (debug=2).
ftp>
ftp>
ftp> rename /path/to/some/directory/filename.txt /path/to/backup/filename_2022-06-01_12:16.txt
---> RNFR /path/to/some/directory/filename.txt
350 File exists, ready for destination name.
---> RNTO /path/to/backup/filename_2022-06-01_12:16.txt
250 file renamed successfully
ftp>
以上是我以 FTP 用户身份登录时尝试使用重命名命令移动它的屏幕截图。
过去几天我一直在研究这个问题,但一无所获。如果有人能帮助我解决这个问题,我将不胜感激。
两台服务器 运行 Red Hat Enterprise Linux
提前致谢。
问题出在文件名上。不支持完整的冒号。因此,我没有附加完整的时间戳,而是将其格式化如下。
ftp.rename(fromname="/path/to/some/directory/filename.txt", toname="/path/to/backup/filename" + "_" + str(datetime.datetime.now().strftime("%Y-%m-%d %H%M%S")).replace(" ", "_") + ".txt")
现在可以使用了。 谢谢@Martin 指出错误。