我有一个 Ubuntu 服务器,使用 SFTP 托管一些.png
文件。
Force UTF-8
当我尝试使用 FileZilla 或 WinSCP 从我的 Windows 笔记本电脑访问这些文件时,如果选中,则文件无法成功传输(现场经理→ 自定义字符集):
这些文件来自在 Windows Server 上运行的 VisualCron,虽然我已在 VisualCron 中将编码更改为 UTF-8,但我不确定它是否适用,因为这是它们唯一可以开始以不同方式编码的地方。
- OpenSSH
sshd_config
:# AcceptEnv LANG LC_* Subsystem sftp = /usr/lib/openssh/sftp-server -l INFO Match Group = sftp_users ChrootDirectory = /ftproot/owners/%u ForceCommand = internal-sftp
请注意,我已注释掉:AcceptEnv LANG LC_*
。根据这里,这意味着服务器将不允许客户端传递语言环境变量。在这种情况下,即使如果使用 VisualCron 的 Windows Server 将使用“错误”编码发送文件,服务器不应该接受它,而应该使用 UTF-8。对吗?
- Ubuntu服务器的区域设置:
LANG = en_US.UTF-8 language = LC_CTYPE = "en_US.UTF-8" LC_NUMERIC = "en_US.UTF-8" LC_TIME = "en_US.UTF-8" LC_COLLATE = "en_US.UTF-8" LC_MONETARY = "en_US.UTF-8" LC_MESSAGES = "en_US.UTF-8" LC_PAPER = "en_US.UTF-8" LC_NAME = "en_US.UTF-8" LC_ADDRESS = "en_US.UTF-8" LC_TELEPHONE = "en_US.UTF-8" LC_MEASUREMENT = "en_US.UTF-8" LC_IDENTIFICATION = "en_US.UTF-8" LC_ALL =
- FileZilla:
使用 时,文件名中包含和ISO-8859-15
等字符的文件可以传输,但传输启用的文件时会出现以下错误:è
é
Force UTF-8
Response: New directory is: "/tickets/" Command: get "FILENAME containing Liège.png" "C:\test\FILENAME containing Liège.png" Error: /tickets/FILENAME containing Liège.png: open for read: no such file or directory Error: File transfer failed
在哪里可以查看我的 SFTP 服务器用于文件列表的编码以及如何将其更改为 UTF-8?
答案1
初步说明:
安全FTP必须使用 UTF-8 作为文件名编码(例如,参见这里作为参考)。但是,有些客户端和服务器不遵循该要求并违反了规范,这可能是导致您出现问题的原因。
你写了:“请注意,我已注释掉:AcceptEnv LANG LC_*。根据这里,这意味着服务器将不允许客户端传递区域设置环境变量。”
关于它的工作原理和用途,可能存在误解。每当两台机器通信时,它们必须使用相同的数据格式。例如,假设 VisualCron 将编码为 ISO 8859-1 的文件名放入它发送到 Ubuntu 服务器的字节流中,但您强制 Ubuntu 服务器将传入的(文件名)字节流解释为 UTF-8 编码。这不会解决问题,但是原因他们。
话虽如此:
我首先会尝试找出问题究竟出在哪里。我强烈假设你有 SSH 访问权限,甚至有物理访问权限(键盘)访问 Ubuntu 服务器。然后
检查 Ubuntu 服务器上是否安装了语言环境
en_US.UTF-8
。请注意,仅设置LC_
和LANG
环境变量并不能不是安装区域设置。相反,您可以在 O/S 安装期间安装语言环境,或者通过类似方法
dpkg-reconfigure locales
(在 debian 上 - 我不知道 Ubuntu)。如果使用 SSH,请确保您的 SSH 终端软件(例如 Putty)使用与服务器相同的编码。
然后,最关键的一步:使用你的 SSH 终端,手动在相应的目录中创建一个具有有问题名称的文件,以便 Windows 笔记本电脑上的 sftp 客户端可以看到它。
例如,回到你的问题,你可以
Liège.txt
在/tickets
目录中创建一个名为的文件(touch /tickets/Liège.txt
)。再次使用你的 SSH 终端,仔细检查当你让 Ubuntu 列出该目录中的文件时文件名是否正确显示(ls -al /tickets
)。现在使用 Windows 笔记本电脑上的 sftp 客户端并检查它是否正确下载了新创建的文件。
如果成功,则说明问题出在 VisualCron 将文件传输到 Ubuntu 服务器时。如果失败,则问题出在您的 Windows 笔记本电脑和 Ubuntu 服务器之间。
在这两种情况下,都有工具可以帮助您分析情况。
例如,您可以通过尝试以下方法获得一些见解:康维,可以将文件名从一种编码转换为另一种编码。值得注意的是,你可以将文件名的编码转换为从 UTF-8 到 UTF-8。当您执行此操作并且确定文件名已经以 UTF-8 编码时,它在转换过程中不得改变。
你可能还想看看沙尔代,这是一个 Python 库,它试图猜测文件名的编码。我不是 Python 专家,所以我无法帮助您提供源代码。根据接受的答案这个问题,您将得到类似 Python 脚本中的一行chardet.detect(os.popen("ls yourfilename.txt").read())
,它将输出最可能的编码以及置信度评级。
总结一下:
确保你的 Ubuntu 服务器上的文件名真的采用 UTF-8 编码,按照上面显示的步骤并使用上面提到的工具。
一旦你完全确定你的 Ubuntu 服务器上的文件名是用 UTF-8 编码的,请检查你的笔记本电脑上的 sftp 客户端是否可以下载它们。如果不行,请尝试其他客户端,直到可以下载为止。
如果您发现 Ubuntu 服务器上并非所有文件名都采用 UTF-8 编码,请相应地调整 VisualCron 中的设置。我不了解 VisualCron,因此无法帮助您。
答案2
SFTP 实际上是 SSH。因此,服务器端没有用于发送/接收 SSH 数据的配置选项。
该问题的解决方案仍然在客户端,因此它将是 WinSCP 配置及其处理非标准字符的兼容性。
看来UTF-8已经是WinSCP和服务器端的标准编码。
答案3
我对包含重音字符的文件的经验是,它们在网络上传输非常不顺畅。我看到的有效解决方案是:
在源处对文件进行 Zip 或 7Zip 压缩,在目标处进行解压。如果需要保留文件权限,请使用 tar。压缩和仅传输一个文件(存档)的事实将大大缩短传输时间。
在两边使用支持重音字符的相同文件传输实用程序进行传输,例如在两台 Linux 或两台 Windows 计算机之间使用文件共享。然而,在 Windows 和 Linux 之间传输时可能会出现问题。
重命名所有文件,使其名称不包含任何重音字符。这是在国际间移动文件时的最佳解决方案。
对于最后一个解决方案,您可以轻松找到 bash 脚本来完成这项工作,例如 slugify.sh。