【问题标题】:How to confirm SFTP file delivery?如何确认 SFTP 文件传送?
【发布时间】:2015-03-29 05:17:27
【问题描述】:

我正在使用 SFTP 和公钥为非 root 用户发送文件,看起来文件已发送,但我无法在目标文件夹中找到它,可能是由于权限。

sftp> ls
sftp> put /tmp/testx
Uploading /tmp/testx to /folder1/target_folder
/tmp/testx                                 100%    5     0.0KB/s   00:01
sftp> get testx
Couldn't stat remote file: No such file or directory
File "/folder1/target_folder/testx" not found.
sftp> ls
sftp>

这里是 -vvv :

debug3: SSH_FXP_REALPATH . -> /folder1
debug3: Looking up /tmp/file_to_send
debug3: Sent message sender_host 4 T:17 I:2
debug3: Wrote 80 bytes for a total of 2653
debug3: Received stat reply T:105 I:2
debug3: Sent message SSH2_FXP_OPEN I:3 P:/folder1/target_directory/file_to_send
debug3: Wrote 112 bytes for a total of 2765
debug3: Sent message SSH2_FXP_WRITE I:4 O:0 S:6206
debug3: Wrote 6288 bytes for a total of 9053
debug3: SSH2_FXP_STATUS 0

目标目录

 drw-rw-rw-    1  0   0       target_directory

如何确保文件在没有服务器访问的情况下交付?

【问题讨论】:

  • 您使用命令行工具而不是直接实现协议并提供有关其处理服务器提供的错误消息的书面保证的客户端库是否有特殊原因?

标签: linux unix ssh sftp


【解决方案1】:

对于完全任意的服务器实现,这是不可能的。 通常希望将传入目录设置为对不受信任的用户只写,以防止滥用公共(或其他广泛)可访问的文件服务器(例如使用它们来托管不相关的内容;曾几何时,盗版者经常使用具有被盗凭据的 FTP 服务器——防止上传的内容在未经行政审查的情况下被下载防止这种情况发生)。因此:如果服务器管理员选择不让您看到上传的文件,那么,您就看不到上传的文件。

但是——SFTP 协议提供了一个契约:如果你告诉服务器在写入之后关闭一个句柄,并且服务器说所有涉及的操作都成功且没有错误,那么如果文件没有被成功接收(无论如何然后服务器决定使用它,这可能包括也可能不包括使其可用于下载),这表明存在服务器端错误,而不是您的 SFTP 客户端的错误。

当我上次实施自定义 SFTP 服务器时——出于客户支持目的,使用 Paramiko 实施——我在成功上传后发送了电子邮件通知;但显然,这是特定于实现的行为)。

【讨论】:

  • 在用户交互模式下,我看到 100% 的进度表明文件已发送,我知道这在批处理模式下不可用。 -vvv 日志中的哪一行相当于这个 "100%" ?换句话说,我应该在日志中查找什么来说明文件已发送?
  • “100%”也不能告诉你太多——它告诉你发送的字节数与预期的字节数相匹配,但这并不意味着它们都被写入了。听起来这不是关于底层 SFTP 协议的问题,而是关于实现该协议的 OpenSSH 命令行工具的代码库;我对前者的了解远胜于后者。
  • 值得注意的是,paramiko 默认情况下会在文件上传后执行stat(),以确保它们的远程和本地大小匹配。 (对于重命名、移动或以其他方式不允许典型客户端访问刚刚上传的文件的服务器,可以禁用此功能)。 如果有效,那么相信没有错误是有意义的,这是一件更确定的事情,但显然它不适用于所有服务器,包括您在这里拥有的服务器。
【解决方案2】:

您所能做的就是在上传文件时检查是否有错误。这就是 SFTP 服务器为您提供的所有信息。

使用命令行 OpenSSH sftp 客户端,您可以检查其退出代码(您需要使用-b 开关)。

echo "put file.txt" | sftp -b - user@host
if [ $? -eq 0 ]
then
    echo "File uploaded"
else
    echo "File NOT uploaded"
fi

另见How to perform checksums during a SFTP file transfer for data integrity?


很可能 SFTP 服务器不允许您下载刚刚上传的文件。

这种行为有两个常见的原因:

  • 公共“上传”目录。这是为了防止您下载其他用户的文件。
  • 有一些进程会立即选择上传的文件进行一些处理。

【讨论】:

    【解决方案3】:

    我知道这是一个旧线程... 这是我能够使用 openssh sftp 客户端将密码验证上传到盲文件夹的最佳方法。 (使用 ftp 更准确...)

    SSHPASS=${PASSWORD} sshpass -e sftp -vvv -oStrictHostKeyChecking=no -oBatchMode=no -b - ${LOGON}@${FTPSITE} >${LOB}ftp.log 2>&1 <<EOF
    pwd
    cd upload
    put ${XMTFILE}
    quit
    EOF
    # sftp does not use FTP codes - it only gives the final status of the requested operation
    Status=$?
    # Not perfect, but sending a single file using -vvv should produce 2 lines containing "debug3: SSH2_FXP_STATUS 0"
    Tmp=`grep "debug3: SSH2_FXP_STATUS 0" ${LOB}ftp.log | wc -l`
    [ ${Tmp} -ne 2 ] && Status=1 # Override sftp exit value based on log info
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多