何にでもGitBashを使うな

# 前書き
この記事は自分のやらかしへの戒めとして、そして同じ失敗を他の誰かに経験して欲しくない一心で作られたものです[^5]。~~こんなアホな失敗、他に誰がやるんだって言われたら、まぁその通りですが。~~

毎度のことではありますが、記事の内容に関して不備がありましたら、ご指摘頂けると幸いです。


# 要約
GitBash使ってて、パーミッション系のエラーでnpmとかのインストールに失敗したら、powershellかコマンドプロンプトでインストールを試みよう。もちろん、その時は管理者権限で起動するのをお忘れなく。

# 環境
OS : Windows 10 Home
git : git version 2.22.0.windows.1
npm : (旧)6.9.0 => (新)6.14.1

(旧)がアップデート前、(新)が今回の一連の騒動でアップデートされたnpmのバージョンです。


# なにが起きたか
去る12月に読んだ、[npmとyarnの脆弱性とpostinstall](https://blog.cybozu.io/entry/npm-vulnerabilities-and-postinstall)に下記のような記載がありました。

> npmの利用者としてやるべきことは、

> * npmのバージョンを6.13.4以上にあげる
> * yarnのバージョンを1.21.1以上にあげる

> です。

記事の詳しい内容はさておき、npmのバージョンを上げなければ、ということは伝わりました。早速自分のnpmのバージョンを確認してみたところ

```shell
$ npm --version
6.9.0
```
はい、いくらなんでも古すぎますね(笑)。ちょっとやばいです。[^10]
そんな訳で早速アップデートします。↓を実行すればいいとのことです。
そして、この時使ったのがお察しの通り、GitBashです。まさかあんなことになるなんて . . .

```shell
$ npm install -g npm
```

暫く時間がかかるかなとPCを放置していました。そして数分後席に戻ってみると、画面には **お び た だ し い 量 の エ ラ ー** がああぁぁぁ！！(火サスのBGM)

<details><summary>エラー全文(長いので注意)</summary><div>

```shell
$ npm install -g npm
C:\Program Files (x86)\Nodist\bin\npx -> C:\Program Files (x86)\Nodist\bin\node_modules\npm\bin\npx-cli.js
npm ERR! code EPERM
npm ERR! Error: EPERM: operation not permitted, open 'C:\Program Files (x86)\Nodist\bin\npm'
npm ERR!     at isClobberable (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:55:3)
npm ERR!     at shimFiles.forEach.to (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:38:27)
npm ERR!     at Array.forEach (<anonymous>)
npm ERR!     at binLink (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:38:13)
npm ERR!     at tryCatcher (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23)
npm ERR!     at ret (eval at makeNodePromisifiedEval (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promisify.js:184:12), <anonymous>:13:39)
npm ERR!     at linkBin (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bin-links\index.js:125:10)
npm ERR!     at BB.map.bin (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bin-links\index.js:90:12)
npm ERR!     at tryCatcher (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23)
npm ERR!     at MappingPromiseArray._promiseFulfilled (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\map.js:61:38)
npm ERR!     at MappingPromiseArray.PromiseArray._iterate (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promise_array.js:114:31)
npm ERR!     at MappingPromiseArray.init (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promise_array.js:78:10)
npm ERR!     at MappingPromiseArray._asyncInit (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\map.js:30:10)
npm ERR!     at _drainQueueStep (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:142:12)
npm ERR!     at _drainQueue (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:131:9)
npm ERR!     at Async._drainQueues (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:147:5)
npm ERR!  { Error: EPERM: operation not permitted, open 'C:\Program Files (x86)\Nodist\bin\npm'
npm ERR!     at isClobberable (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:55:3)
npm ERR!     at shimFiles.forEach.to (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:38:27)
npm ERR!     at Array.forEach (<anonymous>)
npm ERR!     at binLink (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:38:13)
npm ERR!     at tryCatcher (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23)
npm ERR!     at ret (eval at makeNodePromisifiedEval (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promisify.js:184:12), <anonymous>:13:39)
npm ERR!     at linkBin (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bin-links\index.js:125:10)
npm ERR!     at BB.map.bin (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bin-links\index.js:90:12)
npm ERR!     at tryCatcher (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23)
npm ERR!     at MappingPromiseArray._promiseFulfilled (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\map.js:61:38)
npm ERR!     at MappingPromiseArray.PromiseArray._iterate (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promise_array.js:114:31)
npm ERR!     at MappingPromiseArray.init (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promise_array.js:78:10)
npm ERR!     at MappingPromiseArray._asyncInit (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\map.js:30:10)
npm ERR!     at _drainQueueStep (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:142:12)
npm ERR!     at _drainQueue (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:131:9)
npm ERR!     at Async._drainQueues (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:147:5)
npm ERR!   cause:
npm ERR!    { Error: EPERM: operation not permitted, open 'C:\Program Files (x86)\Nodist\bin\npm'
npm ERR!        at isClobberable (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:55:3)
npm ERR!        at shimFiles.forEach.to (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:38:27)
npm ERR!        at Array.forEach (<anonymous>)
npm ERR!        at binLink (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\gentle-fs\lib\bin-link.js:38:13)
npm ERR!        at tryCatcher (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23)
npm ERR!        at ret (eval at makeNodePromisifiedEval (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promisify.js:184:12), <anonymous>:13:39)
npm ERR!        at linkBin (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bin-links\index.js:125:10)
npm ERR!        at BB.map.bin (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bin-links\index.js:90:12)
npm ERR!        at tryCatcher (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23)
npm ERR!        at MappingPromiseArray._promiseFulfilled (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\map.js:61:38)
npm ERR!        at MappingPromiseArray.PromiseArray._iterate (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promise_array.js:114:31)
npm ERR!        at MappingPromiseArray.init (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\promise_array.js:78:10)
npm ERR!        at MappingPromiseArray._asyncInit (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\map.js:30:10)
npm ERR!        at _drainQueueStep (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:142:12)
npm ERR!        at _drainQueue (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:131:9)
npm ERR!        at Async._drainQueues (C:\Program Files (x86)\Nodist\bin\node_modules\npm\node_modules\bluebird\js\release\async.js:147:5)
npm ERR!      message:
npm ERR!       'EPERM: operation not permitted, open \'C:\\Program Files (x86)\\Nodist\\bin\\npm\'',
npm ERR!      code: 'EPERM' },
npm ERR!   stack:
npm ERR!    'Error: EPERM: operation not permitted, open \'C:\\Program Files (x86)\\Nodist\\bin\\npm\'\n    at isClobberable (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\gentle-fs\\lib\\bin-link.js:55:3)\n    at shimFiles.forEach.to (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\gentle-fs\\lib\\bin-link.js:38:27)\n    at Array.forEach (<anonymous>)\n    at binLink (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\gentle-fs\\lib\\bin-link.js:38:13)\n    at tryCatcher (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\release\\util.js:16:23)\n    at ret (eval at makeNodePromisifiedEval (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\release\\promisify.js:184:12), <anonymous>:13:39)\n
 at linkBin (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bin-links\\index.js:125:10)\n    at BB.map.bin (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bin-links\\index.js:90:12)\n    at tryCatcher (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\release\\util.js:16:23)\n    at MappingPromiseArray._promiseFulfilled (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\release\\map.js:61:38)\n    at MappingPromiseArray.PromiseArray._iterate (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\release\\promise_array.js:114:31)\n    at MappingPromiseArray.init (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\release\\promise_array.js:78:10)\n    at MappingPromiseArray._asyncInit (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_e_modules\\npm\\node_modules\\bluebird\\js\\release\\map.js:30:10)\n    at _drainQueueSte(x86)\\Nodist\\bin\\np (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\rue (C:\\Program Fileselease\\async.js:142:12)\n    at _drainQueue (C:\\Program Files (x86)\\Nodist\\bin\\node_:9)\n    at Async._drmodules\\npm\\node_modules\\bluebird\\js\\release\\async.js:131:9)\n    at Async._drainQud\\js\\release\\asynceues (C:\\Program Files (x86)\\Nodist\\bin\\node_modules\\npm\\node_modules\\bluebird\\js\\release\\async.js:147:5)',
npm ERR!   code: 'EPERM' }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
npm ERR! or that you lack permissions to access it.
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\poket\AppData\Roaming\npm-cache\_logs\2020-02-10T14_40_42_375Z-debug.log
```
</div></details>

. . . 長すぎて読む気にもなりません(←読め)
かなり引っ張りましたが、要するにそうです、npmのアップデートに失敗しました(やらかしその1)。


# やらかしていたこと
とにかく長かったので、ざっと全文眺めてみます。すると最後の方に大事そうな文言がありました(# は書き足したものです)。

```shell_session
npm ERR! The operation was rejected by your operating system.  # 1.
npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
npm ERR! or that you lack permissions to access it.  # 2.
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.  # 3.
```

大まかに訳すと、こんな感じでしょうか？

1. 操作がoperating systemによって拒否された
2. そのファイル(?)は、既に(テキストエディタかアンチウィルスソフトが)使っている、あるいはアクセス権限が無い
3. 権限の問題と思うなら、ファイルとディレクトリの権限を見ろ、もしくは管理者権限で再試行せよ

3が怪しいですね。sudoすれば行けるかと思い下記を実行(そういえば、Windowsでsudoなんてできたっけ?)。

```shell
$ sudo npm install -g npm
```

すると、「このアプリがデバイスで変更を加えることを許可しますか？」みたいなアラートが。
　=> とりあえず「はい」を選択してみる。
　=> しばらく待っても、何も起きない。数回やってみるもダメっぽい。
ここで、自分は「自分の環境かnpm自体に問題があって、アップデートは出来ない」のだと思ったわけです。そう、この勘違いこそが本当の意味で今回のやらかしです(やらかしその2)。
GitBashで出来ないなら、そもそも無理なのだと結論を付けてしまいました。


# 他のツール使えばいいじゃん！
Windowsには、標準でコマンドプロンプトやpowershellといった端末[^20]が用意されています。それらは管理者権限で起動する(所謂rootユーザでログインして使う)ことが出来ます。

コマンドプロンプトではパスが通っていないせいか、npm自体を認識できなかったので、powershellを使って再度`npm install`を試みます。Windowsマークを右クリック、Windows Power Shell(管理者)(A)で管理者権限で起動してインストールしてみると

```powershell:powershell
> npm install -g npm
C:\Program Files (x86)\Nodist\bin\npx -> C:\Program Files (x86)\Nodist\bin\node_modules\npm\bin\npx-cli.js
C:\Program Files (x86)\Nodist\bin\npm -> C:\Program Files (x86)\Nodist\bin\node_modules\npm\bin\npm-cli.js
+ npm@6.14.1
added 1 package from 1 contributor and updated 7 packages in 209.259s
```

実行結果を見るに、成功したのでしょうか？gitbashの方で確認します(ここで、powershellを使わなかった理由は別の記事にて)。

```shell:gitbash
> npm --version
6.14.1
```
おお！ちゃんとバージョンが新しくなっています！成功ですね！！

# 結論
* 何にでもGitBashを使うな
* Windowsユーザなら、たまにはpowershellとかコマンドプロンプトとか使おう

以上、長文・乱文失礼いたしました。


[^5]: とはいえ、本当にこんな記事を世に出してもいいものか、ちょっとだけ不安になって、投稿前に利用規約を読み返したりしてました。

[^10]: そういえば、npmでパッケージをインストールした時に、ちょくちょく`New minor version of npm available`みたいなのが出ていましたが、ガン無視してました()

[^20]: 厳密には、端末という表現は正しくない気がしますが、ここではそうしておきます。