ssh - 如何使用 Deno 通过 SSH 传输文件?

标签 ssh deno

我正在寻找一种使用 Deno 通过 SSH 传输文件的方法。我不想允许用户通过网站上传文件,而是想使用 Deno 作为脚本语言将文件上传到服务器,类似于 scppscp。不幸的是,这些都没有在任何 Deno 包装器中使用,所以我想知道如果我想保持交叉兼容性,最好最快的解决方案是什么?

最佳答案

创建包装器比您想象的要简单:您可以使用 subprocess API创建对 scppscp 的调用,并且您可以使用 Deno.build.os 来区分平台环境。将它们结合起来实现您的目标非常简单:

./scp.ts:

const decoder = new TextDecoder();

export type ProcessOutput = {
  status: Deno.ProcessStatus;
  stderr: string;
  stdout: string;
};

/**
 * Convenience wrapper around subprocess API.
 * Requires permission `--allow-run`.
 */
export async function getProcessOutput(cmd: string[]): Promise<ProcessOutput> {
  const process = Deno.run({ cmd, stderr: "piped", stdout: "piped" });

  const [status, stderr, stdout] = await Promise.all([
    process.status(),
    decoder.decode(await process.stderrOutput()),
    decoder.decode(await process.output()),
  ]);

  process.close();
  return { status, stderr, stdout };
}

// Add any config options you want to use here
// (e.g. maybe a config instead of username/host)
// The point is that you decide the API:
export type TransferOptions = {
  sourcePath: string;
  host: string;
  username: string;
  destPath: string;
};

export function createTransferArgs(options: TransferOptions): string[] {
  const isWindows = Deno.build.os === "windows";
  const processName = isWindows ? "pscp" : "scp";
  const platformArgs: string[] = [processName];

  // Construct your process args here using your options,
  // handling any platform variations:
  if (isWindows) {
    // Translate to pscp args here...
  } else {
    // Translate to scp args here...
    // example:
    platformArgs.push(options.sourcePath);
    platformArgs.push(
      `${options.username}@${options.host}:${options.destPath}`,
    );
  }

  return platformArgs;
}

./main.ts:

import * as path from "https://deno.land/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2556514165150b14171c0b15" rel="noreferrer noopener nofollow">[email protected]</a>/path/mod.ts";

import {
  createTransferArgs,
  getProcessOutput,
  type TransferOptions,
} from "./scp.ts";

// locally (relative to CWD): ./data/example.json (or on Windows: .\data\example.json)
const fileName = "example.json";
const sourcePath = path.join(Deno.cwd(), "data", fileName);
// on remote (uses *nix FS paths): /repo/example.json
const destPath = path.posix.join("/", "repo", fileName);

const options: TransferOptions = {
  sourcePath,
  host: "server.local",
  username: "user1",
  destPath,
};

const transferArgs = createTransferArgs(options);
const { status: { success }, stderr, stdout } = await getProcessOutput(
  transferArgs,
);

if (!success) {
  // something went wrong, do something with stderr if you want
  console.error(stderr);
  Deno.exit(1);
}

// else continue...
console.log(stdout);
Deno.exit(0);

关于ssh - 如何使用 Deno 通过 SSH 传输文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71418619/

相关文章:

linux - 如何替换 Amazon EC2 实例的 key 对文件?

linux - 如何自动化两层 SSH 和 docker exec?

python - 从服务器通过 SSH 远程登录

python - 通过 python cgi 脚本的 ssh 不工作

typescript - deno puppeteer 'chrome not found' 尝试导入 npm 依赖项

javascript - 无法解析 deno 中的查询

deno - 在完成测试用例之前关闭从 Deno API 返回的开放资源句柄

python - 使用 pexpect python 模块的 SFTP

javascript - CacheStorage(网络缓存)API 是否关心 Content-Encoding 等 header ?

node.js - Deno 脚本与 Node.js 兼容吗?