Deno.Commandのstdout&errをDeno.stdout&errにリダイレクトする
実は stdout: inherit, stderr: inherit で良い説ないですか?
この記事は他ストリームに書き写すときの手順をDeno.stdout/errで書いたということでお願いします
https://gyazo.com/0239d2983da1a7cfe11e2b11cfc3fc1a
いつの間にかDeno.runがdeprecatedになっていた。かわりにDeno.Commandを使えということらしい。
個人的にDenoは1ファイル完結TS環境として使っているので、spawnは一番多い用途だ。なくなって慌てる前に対応しておきたい。
Deno.Commandになって変わっているところはいくつかあるが、個人的に一番影響が大きかったのは戻り値のstdout/errがDeno.Readerではなくなっているところだ。単なるReadableStreamになっている。相互運用のことを考えると独自型がなくなったのは良いことな気もする。Deno.stdoutに書き出すにはどうしたらよいだろうか。 code:writetostdout.ts
const process = new Deno.Command("curl", {
stdout: "piped",
stderr: "piped",
stdin: "null",
}).spawn();
process.stdout.pipeTo(Deno.stdout.writable);
process.stderr.pipeTo(Deno.stderr.writable);
console.log(await process.status)
愚直にやるとこうなる(と思う)。実行してみる。
code:result
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 38 100 38 0 0 115 0 --:--:-- --:--:-- --:--:-- 116
(REDACTED)
error: Uncaught (in promise) BadResource: Bad resource ID
console.log(await process.status);
^
at Object.print (ext:core/01_core.js:835:32)
at Console.<anonymous> (ext:runtime/98_global_scope.js:126:46)
at console.log (ext:deno_console/01_console.js:3228:20)
at file://signaltest.ts:9:9
at eventLoopTick (ext:core/01_core.js:183:11)
console.logが失敗してしまった。何が起こっているかというと、Deno.stdout/stderrがcloseされてしまっている。
もっと単純に書くとこうである。
code:closetest.ts
Deno.stdout.close();
console.log("piyo");
code:result
error: Uncaught BadResource: Bad resource ID
console.log("piyo");
^
at Object.print (ext:core/01_core.js:835:32)
at Console.<anonymous> (ext:runtime/98_global_scope.js:126:46)
at console.log (ext:deno_console/01_console.js:3228:20)
at file:///signaltest.ts:2:9
pipeToがDeno.stdout/errを閉じてしまっているのである。
preventCloseも効かなかった(というか意味が違う?)ので、ここではとりあえず「閉じられてしまっても良いWritableStreamを作る」方法を紹介する。少し冗長なので、もっと良い方法があれば教えてほしい。
code:writable.ts
const process = new Deno.Command("curl", {
stdout: "piped",
stderr: "piped",
stdin: "null",
}).spawn();
const stdoutWritable = new WritableStream({
write: (chunk) => {
Deno.stdout.write(chunk);
},
});
const stderrWritable = new WritableStream({
write: (chunk) => {
Deno.stderr.write(chunk);
},
});
process.stdout.pipeTo(stdoutWritable);
process.stderr.pipeTo(stderrWritable);
console.log(await process.status);
ここで新しく作ったstdoutWritable/stderrWritableは閉じられてしまってもDeno.stdout/errに影響しないため大丈夫という寸法だ。書き込み順序が気になる場合は、writeしている部分をwriteSyncしたりすれば良さそうに思う。
まとめ
stdout閉じれるなよ