1

我们在 K8 环境中运行一个 golang 应用程序,它在某一时刻将生成的文件推送到外部 SFTP 服务器,配置为 sftp://user:pass@host:22/upload/sftp2

在服务器上创建/打开文件的代码是......

    import (
        "github.com/pkg/sftp"
        "golang.org/x/crypto/ssh"
    )

    config := &ssh.ClientConfig{
        User: cred.RemoteUserName,
        Auth: []ssh.AuthMethod{
            ssh.Password(cred.RemotePassword),
        },
        Timeout:         time.Duration(30) * time.Second,
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    conn, err := ssh.Dial("tcp", addr, config)
    sftpConn, err := sftp.NewClient(conn)

    destFolder := ""
    if upload.DstFileDir != "." && upload.DstFileDir != "" {
        destFolder = upload.DstFileDir
    }
    dst := path.Join(destFolder, upload.DstFileName)
    log.Printf("Opening dest file: [%s]", dst)

    dstFile, err := sftpConn.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)

其中 upload.DstFileDir = upload/sftp2 使用正则表达式从上面配置的 url 中提取。

然而,我们偶然发现了一个奇怪的行为,我们在 sftpConn.OpenFile 语句中收到 EOF 错误......

2021-04-06 00:39:18.459584 我 | 打开 dest 文件:[upload/sftp2/sample.001]
2021-04-06 00:39:18.461778 I | 由于 sftp 创建/打开错误 [EOF],上传文件 sample.001 失败

...但是,如果我们像下面这样对文件夹名称进行硬编码,则文件将成功上传。

dst := path.Join("upload/sftp2", upload.DstFileName)

或者

destFolder := "upload/sftp2"
dst := path.Join(destFolder, upload.DstFileName)

2021-04-06 00:13:00.787883 我 | 打开 dest 文件:[upload/sftp2/sample.001]
2021-04-06 00:13:00.787883 I | 文件 /home/user/sample.001 上传成功 sftp 服务器。

  • 如果我们在 vscode 中调试代码,一切正常。
  • 显然,这种行为是在 k8 POD 中运行应用程序时观察到的。
  • 如果我们编写一个足以上传文件的独立 golang 应用程序,并从同一个 POD 执行二进制文件,它就可以正常工作。
  • 尝试使用没有路径的直接字符串连接。没有运气就加入。
  • 尝试使用绝对路径,在开始时使用“./”或“/”或没有 / 的相对路径,但没有运气。

依赖项及其版本:

github.com/pkg/sftp v1.12.0 // 间接
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // 间接 golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // 间接
golang.org
/x/sys v0.0.0-20210119212857-b64e53b001e4 //间接
golang版本1.16.1

当 path.Join 仅返回字符串时,为什么形成字符串的特定方式会影响在 sftp 服务器上打开文件?

4

0 回答 0