search
LoginSignup
7
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

cmd.exeでbashのバックティックのようにコマンドの出力を埋め込む

npmはnpm binとすることで現在のnode_modulesの実行ファイルが置かれているディレクトリへのパスを出力できるのですが、

> npm bin
d:\src\js\node_modules\.bin

cmd.exeだとこれをどうやって利用すればいいのか分からなかったので調べてみました。

(例えばbashなんかだとバックティックを使って、

> `npm bin`/mocha

のようにしてローカル(-gを付けてインストールしたわけではない)のコマンドを実行できるのですけど…)

結論からすると、次のようにすればいいようです。

> for /F "tokens=*" %a in ('出力を利用するコマンド') do %aに出力が入っているのでそれを利用する

さきほどのbashのnpmの例を書き直してみると、

> for /F "tokens=*" %a in ('npm bin') do %a\mocha

のようになります。

解説

forというのはcmd.exeに元から組み込まれている(?)コマンドの一つで、ヘルプ(/?)には次のように書かれています。

指定されたコマンドをファイル セットの各ファイルに対して実行します。

FOR %変数 IN (セット) DO コマンド [コマンドパラメーター]

ようするに、セットという部分に入ったファイルセット(ファイル名のリストみたいなもの、ワイルドカードを展開したりする)を一つずつ%変数という変数に代入してDO以下のコマンドを実行します。
PythonやJavaScriptのfor inによるループをイメージしてもらうといいかもしれません。

で、なぜそのループ用のコマンドがbashのバックティックの代わりになるのかと言うと、/Fというオプションに秘密があります。
/Fを付けると、ファイルセットの中にあるシングルクオートに囲まれた文字列をコマンドとして解釈し、その出力を解析して%変数に渡す、という機能が追加されます。(他にも色々追加されます)
今やりたいことにうってつけの機能ですね。

ただ、そのままに/Fを付けると少々厄介な問題が生じます。
具体的には、npm binc:\Program Files\node\node_modulesのように空白を含むパスを返したとします。すると素の/Fでは、

> for /F %a in ('npm bin') do @echo %a
c:\Program

のように、空白で区切られてしまい、途中までしか取得することができません。

そこで、"tokens=*"というオプションを付けます。
すると、空白で区切られたものも取得することができるようになります。どういう原理なのかは説明するのが面倒なのでfor /?を実行するかここらへんを参照してください。

最後に注意事項ですが、出力が複数行に及ぶ場合は行ごとに勝手に分けられてしまうのでご注意を。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
7
Help us understand the problem. What are the problem?