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 binがc:\Program Files\node\node_modulesのように空白を含むパスを返したとします。すると素の/Fでは、
> for /F %a in ('npm bin') do @echo %a
c:\Program
のように、空白で区切られてしまい、途中までしか取得することができません。
そこで、"tokens=*"というオプションを付けます。
すると、空白で区切られたものも取得することができるようになります。どういう原理なのかは説明するのが面倒なのでfor /?を実行するかここらへんを参照してください。
最後に注意事項ですが、出力が複数行に及ぶ場合は行ごとに勝手に分けられてしまうのでご注意を。