【问题标题】:ssh2-sftp-client get() request giving 'denied permission - error'ssh2-sftp-client get() 请求给出“拒绝权限 - 错误”
【发布时间】:2020-07-03 01:49:10
【问题描述】:

我在我的电子应用程序中使用此代码连接到我需要收集一些数据的 sftp 服务器。列出 /out 文件夹中的文件没有问题,但无法获取带有“定义权限”错误的 sftp 文件。理想情况下,我希望能够 get() 文件并直接在函数中访问文本数据,而无需存储到文件中。

let Client = require('ssh2-sftp-client');
let sftp = new Client();

var root = '/out';
var today = new Date();
var mon = ((today.getMonth()+1) < 10)? "0" + (today.getMonth()+1) : (today.getMonth()+1);
var date = (today.getDate() < 10)? "0" + today.getDate() : today.getDate();
var fileDate = mon + date;   


sftp.connect({
    host: '<server-address>',
    port: 2222,
    username: 'XXXXXXXX',
    password: 'xxxxxxxx',
    privateKey: fs.readFileSync(path.join(__dirname, '../rsa/<file-name-here>.pem'))
})
.then(() => {
    return sftp.list(root, 'SN5M' + fileDate);
})
.then((fileInfo) => { 
    if (fileInfo) {
        var filePath = root + '/' + fileInfo[fileInfo.length - 1].name;
        return sftp.get(filePath).then((file) => {
            console.log(file);
            event.returnValue = file;
            sftp.end();
        })
        .catch((err) => {
            console.log('File get error', err);
            event.returnValue = err;
            sftp.end();
        });
    }
})
.catch((err) => {
    console.log('File info error', err);
    event.returnValue = err;
    sftp.end();
});

【问题讨论】:

  • 你遇到了什么错误?
  • 我应该提一下!,我收到“错误:sftp.get: Permission denied at formatError”
  • 你的代码执行是否进入了'if (fileInfo) {' 块?同时打印并检查 filePath 值。
  • 是的,进入if语句,文件路径按预期出来
  • 检查您是否有权读取该文件

标签: node.js ssh electron rsa


【解决方案1】:

试试这个,看看它是否有效

'get' 返回 (String|Stream|Buffer)。

let dst = fs.createWriteStream('/local/file/path/data.txt');
sftp.get(filePath,dst)

参考https://www.npmjs.com/package/ssh2-sftp-client#orga0dfcd5

【讨论】:

    【解决方案2】:

    查看您的代码,您有两个问题。

    1. 如果你只用 1 个参数调用 get(),它会返回一个缓冲区,而不是一个文件。要获取文件,只需执行

      client.get(sourceFilePath, localFilePath)

    该文件将在本地保存为localFilePath。两个参数都是字符串,并且需要是完整路径,即包括文件名,而不仅仅是目录。第二个参数的文件名可以与第一个不同。但是,如果您只想检索文件,最好使用fastGet() 而不是get()。 get() 方法适用于当您想在代码中对数据执行某些操作时,例如缓冲区或写入流管道/处理。 fastGet() 方法比 get() 更快,因为它使用并发进程进行传输,但不允许使用缓冲区或流进行进一步处理。

    1. 您看到的错误消息是由于您调用 get() 的方式,或者表明您没有权限读取您尝试访问的文件(作为您连接的用户)。最简单的检查方法是使用 openSSH sftp 程序(在 Linux、mac 和 Windows 上可用)和您使用的密钥(使用 -i 开关)来尝试下载文件。如果它因权限错误而失败,那么您就知道这是一个权限错误,而不是您的代码或 ssh2-sftp-client 模块的问题。

    编辑:我刚刚注意到您还同时使用了密码和密钥文件。您不需要两者都需要 - 任何一个都可以,但您不需要同时使用两者。我倾向于尽可能使用密钥文件,因为它避免了将密码存储在某处。确保不要向您的密钥添加密码。或者,您可以使用 dotenv 模块之类的东西,并将您的凭据和其他配置存储在 .env 文件中,您不检查版本控制。

    【讨论】:

    • 谢谢蒂姆,这真的很有帮助。我已经设法使用 fastGet() 和目的地获取文件。 let dst = path.join(__dirname, '../data.txt'); return sftp.fastGet(filePath, dst.toString()).then((file) =&gt; { console.log(file); event.returnValue = file; sftp.end(); }) 文件中的信息只是简单的文本,我真正想要的是能够直接将文本获取到函数中,而无需将文件检索到文件夹中。我可以使用 get() 并操作缓冲区吗?
    • 是的,尤其是在文件不太大的情况下。如果你只向 get() 传递一个参数,它将返回一个 Buffer 对象,然后你可以做任何你想做的事情。或者,您可以传入一个可写流,然后您可以在 pipe() 中使用它来操作它(例如,我这样做是为了获取一个 *.gz 文件,“即时”解压缩它,然后将其通过管道传输到另一个处理数据的流)。 Streams 最适合较大的文件,但当数据较小时,您也可以只使用 Buffer 来做类似的事情。
    • 谢谢蒂姆,我已经尝试了所有我能找到的例子,但 get() 总是返回“权限被拒绝错误”,而 fastGet() 将文件下载到目的地没有问题。
    • 它应该可以工作。在这里发布你的代码示例或在模块的 git 存储库中创建一个问题,我会看看它为什么不工作。
    猜你喜欢
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多