例えば「dir "C:¥ab c"」のようなコマンドを実行したい場合、「Deno.run({cmd:['cmd', '/C dir "C:¥ab c"']})」とすれば良い…かと思いきや、それを実行するとコマンドラインに渡る文字列は「cmd /C dir ¥"C:¥ab c¥"」となってしまいます。
これがどうにか回避できないと非常に困るので色々試した結果が以下。
これがどうにか回避できないと非常に困るので色々試した結果が以下。
結論から言うと、v1.10.2ではバッチファイルを一時的に作成・実行することで回避できます。
具体的な手順は以下。
- カレントディレクトリに存在しないファイル名を探す。
- 上記で見つけた名前でバッチファイルを作成する。
- バッチファイルの中に、実行したいコマンドを書き込む。
- Deno.runで上記バッチファイルを実行して出力を読み取る。
- バッチファイルを削除する。
カレントディレクトリに対して書き込み権限がないと使えませんが、それさえクリアすれば、とりあえずこれで何とかなりそう。
上記の手順を反映したソースが以下。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function 一時ファイルを作成(value:string){ | |
const path作成 = function(中間:string){return 'tmp_'+(new Date()).getTime()+中間+'.bat'} | |
let path = path作成('') | |
let cnt = 0 | |
while(await fileExists('./'+path)){ | |
path = path作成('-' + (cnt++)) | |
console.log(path) | |
} | |
await Deno.writeTextFile(path, value) | |
return path | |
} | |
async function fileExists(path: string): Promise<boolean> { | |
console.log(path) | |
try { | |
await Deno.lstat(path) | |
return true | |
} catch (err) { | |
if (err instanceof Deno.errors.NotFound) { | |
return false | |
} | |
throw err | |
} | |
} | |
const path = await 一時ファイルを作成('chcp 65001 & dir "D:\\abc\\de f"') | |
console.log(path) | |
const p = Deno.run({cmd:['cmd', '/C', path], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) | |
Deno.remove(path) |
以降は上記のソースに辿り着くまでに試したサンプルです。
スペースを含まないPathなら問題なく動作する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C', 'chcp 65001 &', 'dir', 'D:\\abc'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
スペースを含むPathだと意図した結果にならない。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C', 'chcp 65001 &', 'dir', 'D:\\abc\\de f'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
バッチファイルのPathの先頭に「./」がついているとcmdがエラーになっちゃう。
(しかしバッチファイル出力時に上書きを防ぐためにfileExistsにpathを渡す時は「./」が無いとエラーになっちゃう)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function 一時ファイルを作成(value:string){ | |
const path = './deno_tmp.bat' | |
await Deno.writeTextFile(path, value) | |
return path | |
} | |
const path = await 一時ファイルを作成('chcp 65001 & dir "D:\\abc\\de f"') | |
console.log(path) | |
const p = Deno.run({cmd:['cmd', '/C', path], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
以下のサンプルで、バッチファイル経由でのdir実行が可能なことが確認できた。
あとはバッチファイル出力時に既存のファイルを上書きしないようにPathを調整する機能を加えて、冒頭の完成サンプルとした。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function 一時ファイルを作成(value:string){ | |
const path = 'deno_tmp.bat' | |
await Deno.writeTextFile(path, value) | |
return path | |
} | |
const path = await 一時ファイルを作成('chcp 65001 & dir "D:\\abc\\de f"') | |
console.log(path) | |
const p = Deno.run({cmd:['cmd', '/C', path], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) | |
Deno.remove(path) |
以降は、バッチファイルを使わずにDeno.runに渡すパラメータを工夫して回避する、というのをechoで試してみた結果です。
結論から言うと、その方法では無理そうでした。
基本形
スペースを含まない文字なら問題ない。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C', 'echo 123'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
以下は色々試したけど全部だめだった。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C echo 123'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C echo "123"'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C echo "12 3"'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C echo "12 3" '], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C echo', 123], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C echo', '123'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C', 'echo', '123'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C', 'echo', '"123"'], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C', 'echo', "'123'"], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p = Deno.run({cmd:['cmd', '/C', 'echo', "`123`"], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o); | |
console.log(text) |
ちなみに、スペースを含む文字列をコマンドに渡す際、ダブルクォーテーション以外の物で囲ってみたりスペースをエスケープできないかと色々試してみましたが、ダメでした。仕様的にもそうなっている筈なので、当然ですが…。
0 件のコメント:
コメントを投稿