如何通过node-ssh从远程复制文件到本地Node.js目录(无SFTP权限)
问题分析与解决方案
错误原因
你通过ssh.execCommand()执行的scp命令是在远程服务器端运行的,此时命令中的${localZipPath}指向的是远程服务器自身的文件路径,而非你本地Node.js项目的文件夹,所以文件被复制到了远程服务器的对应目录,而非本地。
解决方案:本地执行SCP命令
由于无法使用SFTP,推荐直接在本地机器执行scp命令(通过Node.js的child_process模块调用),这样才能将远程文件拉取到本地项目中。
代码示例
const { exec } = require('child_process'); const util = require('util'); const path = require('path'); // 把exec转为Promise形式,方便异步调用 const execPromise = util.promisify(exec); const sshConfig = { host: config.host, port: 22, username: config.hostname, password: config.hostpassword, }; const zipFileName = "你的文件名.zip"; // 替换为实际文件名 const localZipPath = path.resolve(__dirname, `./uploads/${zipFileName}`); // 使用绝对路径更可靠 const remoteZipPath = path.posix.join(remoteDirectory, zipFileName); // 构造本地执行的SCP命令:格式为 scp -P 端口 用户名@远程主机:远程文件路径 本地路径 const scpCmd = `scp -P ${sshConfig.port} ${sshConfig.username}@${sshConfig.host}:${remoteZipPath} ${localZipPath}`; try { const { stdout, stderr } = await execPromise(scpCmd); if (stderr) { console.error('SCP执行出错:', stderr); } else { console.log('文件成功复制到本地:', stdout); } } catch (err) { console.error('命令执行失败:', err.message); }
注意事项
- 端口参数:scp的端口参数是大写
-P,和ssh命令的小写-p不同,不要混淆。 - 密码处理:如果本地未配置SSH免密登录,需要手动输入密码。若要自动输入密码,可使用
sshpass工具,命令修改为:
注意:明文传递密码存在安全风险,生产环境优先使用SSH密钥登录。sshpass -p "${sshConfig.password}" scp -P ${sshConfig.port} ${sshConfig.username}@${sshConfig.host}:${remoteZipPath} ${localZipPath} - 绝对路径:使用
path.resolve()生成本地绝对路径,避免因工作目录变化导致路径错误。
内容的提问来源于stack exchange,提问作者chethu
相关产品推荐
相关产品推荐

