使用 Deno.run 以 7z 提取文件
Use Deno.run to extract a file with 7z
尝试编写一个小脚本来自动执行某些任务。选择 deno 作为一种很好的独立方式来执行我需要的随机自动化任务——以及一个学习机会。
我正在尝试做的一件事是使用 7z 提取存档,但我不明白为什么它不起作用。
let cmdProcess = Deno.run({
cmd: ["7z", "e ProcessExplorer.zip"],
stdout: "piped",
stderr: "piped"
})
const output = await cmdProcess.output()
const outStr = new TextDecoder().decode(output);
console.log(outStr)
const errout = await cmdProcess.stderrOutput()
const errStr = new TextDecoder().decode(errout);
console.log(errStr)
7z 根据正常输出执行 运行。但是无论我尝试将什么参数传递给 7z,我都会收到以下错误:
Command Line Error:
Unsupported command:
x ProcessExplorer.zip
无论我提供完整路径还是相对路径,或者我给出什么命令都没有关系。
我可能向 Deno.run
提供了错误的参数,但我无法 google Deno.run()
因为大多数搜索结果最终都是针对 deno run
CLI 命令。
我在 Win 10 21H2.
deno v1.19.3
如果您将 e
子命令与参数 ProcessExplorer.zip
:
分开,它应该可以工作
const cmdProcess = Deno.run({
cmd: ["7z", "e", "ProcessExplorer.zip"],
stdout: "piped",
stderr: "piped",
});
使用 Deno.run
时,您需要将命令的所有不同 subcommands/options/flags 拆分为 cmd
数组中的单独字符串,如前所述
有关 Deno 命名空间 API 的文档,您可以在 https://doc.deno.land. For Deno.run
specifically you can find it here 找到它。
这是使用 Deno 7z
提取档案的基本功能抽象:
./process.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 };
}
./7z.ts
:
import { getProcessOutput, type ProcessOutput } from "./process.ts";
export { type ProcessOutput };
// Ref: https://sevenzip.osdn.jp/chm/cmdline/index.htm
export type ExtractOptions = {
/**
* Extract nested files and folders to the same output directory.
* Default: `false`
*/
flat?: boolean;
/**
* Destination directory for extraction of archive contents.
* 7-Zip replaces the `"*"` character with the name of the archive.
* Default: (the current working directory)
*/
outputDir?: string;
/** Overwrite existing files. Default: `true` */
overwrite?: boolean;
};
/**
* Extract the contents of an archive to the filesystem using `7z`.
* Requires `7z` to be in your `$PATH`.
* Requires permission `--allow-run=7z`.
*
* @param archivePath - Path to the target archive file
* @param options - Extraction options
*/
export function extractArchive(
archivePath: string,
options: ExtractOptions = {},
): Promise<ProcessOutput> {
const {
flat = false,
outputDir,
overwrite = true,
} = options;
const cmd = ["7z"];
// https://sevenzip.osdn.jp/chm/cmdline/commands/extract.htm
// https://sevenzip.osdn.jp/chm/cmdline/commands/extract_full.htm
cmd.push(flat ? "e" : "x");
// https://sevenzip.osdn.jp/chm/cmdline/switches/overwrite.htm
cmd.push(overwrite ? "-aoa" : "-aos");
// https://sevenzip.osdn.jp/chm/cmdline/switches/output_dir.htm
if (outputDir) cmd.push(`-o${outputDir}`);
// Disable interaction
// https://sevenzip.osdn.jp/chm/cmdline/switches/yes.htm
cmd.push("-y");
cmd.push(archivePath);
return getProcessOutput(cmd);
}
用法示例:
./main.ts
:
import { extractArchive, type ExtractOptions } from "./7z.ts";
async function main() {
const { status: { code, success }, stdout, stderr } = await extractArchive(
"example.zip",
);
if (!success) { // Something went wrong
console.error(`7-Zip exited with code: ${code}`);
console.error(stderr);
Deno.exit(1);
}
// Extraction was successful
console.log(stdout);
}
if (import.meta.main) main();
> deno run --allow-run=7z main.ts
Check file:///C:/Users/deno/so-71445897/main.ts
7-Zip 21.07 (x64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-12-26
Scanning the drive for archives:
1 file, 774 bytes (1 KiB)
Extracting archive: example.zip
--
Path = example.zip
Type = zip
Physical Size = 774
Everything is Ok
Folders: 3
Files: 2
Size: 38
Compressed: 774
尝试编写一个小脚本来自动执行某些任务。选择 deno 作为一种很好的独立方式来执行我需要的随机自动化任务——以及一个学习机会。
我正在尝试做的一件事是使用 7z 提取存档,但我不明白为什么它不起作用。
let cmdProcess = Deno.run({
cmd: ["7z", "e ProcessExplorer.zip"],
stdout: "piped",
stderr: "piped"
})
const output = await cmdProcess.output()
const outStr = new TextDecoder().decode(output);
console.log(outStr)
const errout = await cmdProcess.stderrOutput()
const errStr = new TextDecoder().decode(errout);
console.log(errStr)
7z 根据正常输出执行 运行。但是无论我尝试将什么参数传递给 7z,我都会收到以下错误:
Command Line Error:
Unsupported command:
x ProcessExplorer.zip
无论我提供完整路径还是相对路径,或者我给出什么命令都没有关系。
我可能向 Deno.run
提供了错误的参数,但我无法 google Deno.run()
因为大多数搜索结果最终都是针对 deno run
CLI 命令。
我在 Win 10 21H2.
deno v1.19.3
如果您将 e
子命令与参数 ProcessExplorer.zip
:
const cmdProcess = Deno.run({
cmd: ["7z", "e", "ProcessExplorer.zip"],
stdout: "piped",
stderr: "piped",
});
使用 Deno.run
时,您需要将命令的所有不同 subcommands/options/flags 拆分为 cmd
数组中的单独字符串,如前所述
有关 Deno 命名空间 API 的文档,您可以在 https://doc.deno.land. For Deno.run
specifically you can find it here 找到它。
这是使用 Deno 7z
提取档案的基本功能抽象:
./process.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 };
}
./7z.ts
:
import { getProcessOutput, type ProcessOutput } from "./process.ts";
export { type ProcessOutput };
// Ref: https://sevenzip.osdn.jp/chm/cmdline/index.htm
export type ExtractOptions = {
/**
* Extract nested files and folders to the same output directory.
* Default: `false`
*/
flat?: boolean;
/**
* Destination directory for extraction of archive contents.
* 7-Zip replaces the `"*"` character with the name of the archive.
* Default: (the current working directory)
*/
outputDir?: string;
/** Overwrite existing files. Default: `true` */
overwrite?: boolean;
};
/**
* Extract the contents of an archive to the filesystem using `7z`.
* Requires `7z` to be in your `$PATH`.
* Requires permission `--allow-run=7z`.
*
* @param archivePath - Path to the target archive file
* @param options - Extraction options
*/
export function extractArchive(
archivePath: string,
options: ExtractOptions = {},
): Promise<ProcessOutput> {
const {
flat = false,
outputDir,
overwrite = true,
} = options;
const cmd = ["7z"];
// https://sevenzip.osdn.jp/chm/cmdline/commands/extract.htm
// https://sevenzip.osdn.jp/chm/cmdline/commands/extract_full.htm
cmd.push(flat ? "e" : "x");
// https://sevenzip.osdn.jp/chm/cmdline/switches/overwrite.htm
cmd.push(overwrite ? "-aoa" : "-aos");
// https://sevenzip.osdn.jp/chm/cmdline/switches/output_dir.htm
if (outputDir) cmd.push(`-o${outputDir}`);
// Disable interaction
// https://sevenzip.osdn.jp/chm/cmdline/switches/yes.htm
cmd.push("-y");
cmd.push(archivePath);
return getProcessOutput(cmd);
}
用法示例:
./main.ts
:
import { extractArchive, type ExtractOptions } from "./7z.ts";
async function main() {
const { status: { code, success }, stdout, stderr } = await extractArchive(
"example.zip",
);
if (!success) { // Something went wrong
console.error(`7-Zip exited with code: ${code}`);
console.error(stderr);
Deno.exit(1);
}
// Extraction was successful
console.log(stdout);
}
if (import.meta.main) main();
> deno run --allow-run=7z main.ts
Check file:///C:/Users/deno/so-71445897/main.ts
7-Zip 21.07 (x64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-12-26
Scanning the drive for archives:
1 file, 774 bytes (1 KiB)
Extracting archive: example.zip
--
Path = example.zip
Type = zip
Physical Size = 774
Everything is Ok
Folders: 3
Files: 2
Size: 38
Compressed: 774