我正在寻找一种使用 Deno 通过 SSH 传输文件的方法。我不想允许用户通过网站上传文件,而是想使用 Deno 作为脚本语言将文件上传到服务器,类似于 scp
或 pscp
。不幸的是,这些都没有在任何 Deno 包装器中使用,所以我想知道如果我想保持交叉兼容性,最好最快的解决方案是什么?
最佳答案
创建包装器比您想象的要简单:您可以使用 subprocess API创建对 scp
或 pscp
的调用,并且您可以使用 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/