我们在 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 服务器上打开文件?