全Scoopコマンド解説 その２ ～使用頻度（中）～

# はじめに

前回に引き続き、各Scoopコマンドについて解説していきます。

今回はやや使うことのあるサブコマンドをメインに取り上げます。
使用頻度は”やや”ですが、よりScoopを快適に使用するためにはどれも役に立つコマンドです。

また、コマンドの中には存在意義が分かりづらいものもあるので、
今回からScoop内部の話（`~\scoop`のフォルダ構成など）が若干強めになります。

|#| 記事リンク | 使用頻度 | Scoopサブコマンド |
|:-:|:-:|:-:|:-----------------|
|-| [全Scoopコマンド解説 その１ ～使用頻度（高）～](https://qiita.com/nimzo6689/items/1ab33380366e324c0b84) | 高 | help, search, bucket, install, list, info, status, update, uninstall |
|今回はココ→| 全Scoopコマンド解説 その２ ～使用頻度（中）～ | 中 | home, cache, cleanup, hold, unhold, which, reset, checkup |
|-| [全Scoopコマンド解説 その３ ～使用頻度（低）～](https://qiita.com/nimzo6689/items/53c63439f56ccd2d38c1) | 低 | config, alias, create, depends, export, prefix, virustotal |
※表中のサブコマンドの並びに沿って紹介していきます。

# home

Scoopアプリのホームページを開くコマンドです。

```powershell:構文
scoop home <app>
```

実行すると標準ブラウザでScoopアプリに指定されているホームページが表示されます。
そのアプリの公式サイトであったり、GitHubのページであったりです。

使うタイミングですが、Scoopコマンド経由でしかアプリを確認していないと
本当にそのScoopアプリ名がユーザが想定しているアプリと一致しているのかが分かりづらいケースがあるため
その確認目的で使用するケースがメインかと思います。

あるいは、単純に公式サイトを表示するためのショートカット。

```powershell:例
# gitのホームページを表示
# Git for Windowsのページが表示されます。
scoop home git
```

# cache

Scoopアプリのキャッシュを検索、削除するコマンドです。

```powershell:構文
scoop cache show|rm [app]
```

ここでいうキャッシュという意味ですが、Scoopアプリのインストールするための元ファイルのことです。

少し内部の話になってしまいますが、Scoopはアプリをインストールする際、
Bucket内にjsonで書かれているマニフェストファイルの情報を元に各アプリの元となるファイル
（setup.exeなどのインストーラーや単純にzipファイルなど）をスクレイピングで取得しています。

取得後は、この元となるファイルを展開し（必要があればインストーラーを起動して）
`~\scoop\apps`フォルダ配下にインストールしています。
その後、元となったファイルは不要になるのですが、再インストールする際に再度Webから取得する処理を省くため、
`~\scoop\cache`フォルダ配下に展開前の元ファイルをキャッシュとして保持するようにしているわけです。

便利な仕組みではありますが、これをずっと放置していると気づけば数GB、数十GBになってしまう可能性もあるため
定期的に削除するように心がけましょう。

```powershell:例
# キャッシュ済みのインストーラーを全て確認（最後に表示したキャッシュの合計となる容量が表示されます。便利。）
scoop cache show
#=>99.3 MB adopt8-hotspot (8u212-b04)   https_github.com_AdoptOpenJDK_openjdk8-binaries_releases_download_jdk8u212-b04_OpenJDK8U-jdk_x64_windows_hotspot_8u212b04.zip
#=> 81.9 MB anki (2.1.13)               https_apps.ankiweb.net_downloads_current_anki-2.1.13-windows.exe_dl.7z
#=>...
#=>Total: 76 files, 4.4 GB

# giboのキャッシュのみ確認
scoop cache show gibo
#=>9.2 KB gibo (2.2.1)   https_github.com_simonwhitaker_gibo_archive_2.2.1.zip
#=>9.3 KB gibo (2.2.2)   https_github.com_simonwhitaker_gibo_archive_2.2.2.zip
#=>
#=>Total: 2 files, 18.5 KB

# 不要なキャッシュを削除したい場合
scoop cache rm gibo
scoop cache show gibo
#=>Total: 0 files, 0 B

# 全てのキャッシュを削除したい場合
scoop cache rm *
scoop cache show
#=>Total: 0 files, 0 B
```

# cleanup

使用していないバージョンのインストール済みScoopアプリを削除するコマンドです。

```powershell:構文
scoop cleanup (* | <app> | <app> ...) [options]
```

指定されたScoopアプリで使用されていないバージョンがまだローカル内に保持されている場合、それらを削除します。
現行のバージョン以外が存在しない場合は「<app> is already clean」と表示されます。
全てのScoopアプリの古いバージョンをローカル内から削除したい場合は scoop cleanup * とすることで削除可能です。

Scoopのupdateコマンドは単純に新しいバージョンをinstallしているだけなので、
古いバージョンのファイル群は何もしなければずっと`~\scoop\apps`配下に残るようになってしまいます。
これらもキャッシュと同様、使用済みの容量が増える一方になるため、定期的に削除が必要です。

```powershell:例
# 現行のバージョンとインストール済みの全バージョンを確認
scoop info postman
#=>Name: postman
#=>Version: 7.3.0 (Update to 7.3.1 available)
#=>...
#=>Installed:
#=>  C:\Users\xxxxx\scoop\apps\postman\7.1.1
#=>  C:\Users\xxxxx\scoop\apps\postman\7.2.2
#=>  C:\Users\xxxxx\scoop\apps\postman\7.3.0
#=>...

# 未使用となっているバージョンを削除
scoop cleanup postman
#=>Removing postman: 7.1.1 7.2.2

# 現行以外のインストール済みのバージョンが削除されていることを確認
scoop info postman
#=>Name: postman
#=>Version: 7.3.0 (Update to 7.3.1 available)
#=>...
#=>Installed:
#=>  C:\Users\xxxxx\scoop\apps\postman\7.3.0
#=>...

# cleanupを再実行する方法でも確認可能
scoop cleanup postman
#=>postman is already clean
```

また、以下のオプションも指定可能です。

| ショートオプション | ロングオプション | 説明 |
|:-:|:--|:--|
|-g|--global|グローバルにインストールされたScoopアプリを対象にします。|
|-k|--cache|古いバージョンとなったダウンロードキャッシュを削除します。|

# hold

今インストールしているScoopアプリのバージョンを固定するコマンドです。

```powershell:構文
scoop hold (<app> | <app> ...)
```

新たに更新可能なバージョンが出てもupdateコマンドで更新されないようにできます。
解除はunholdコマンド（詳細は後述）で可能です。

hold中のアプリは`scoop list`や`scoop status`で確認することができます。

```powershell:例
scoop hold go
#=>go is now locked and can not be updated anymore.

scoop update go 
#=>WARN 'go' is locked to version 1.12.5 
#=>Latest versions for all apps are installed! For more information try 'scoop status'
```

# unhold

hold中のアプリをhold解除するコマンドです。

```powershell:構文
scoop unhold (<app> | <app> ...)
```

特に解説不要なので、以下の使用例だけ載せておきます。

```powershell:例
# listコマンドでgoのインストール状況を表示
scoop list go
#=>Installed apps matching 'go':
#=>
#=>  go 1.12.6 *hold*

# goのholdを解除
scoop unhold go
#=>go is now unlocked and can be updated again.

# 再度インストール状況を表示
scoop list go
#=>Installed apps matching 'go':
#=>
#=>  go 1.12.6
```

# which

Linuxでいう`which`コマンド、Windowsでいう`where`コマンドです。

```powershell:構文
scoop which <command>
```

いまいち、こちらのコマンドの存在意義がわからないかもしれませんが、
その意義はScoopの持つPATH変数を汚さない仕組みに隠されています。

通常、開発に使用するコマンドツールを例えば50個インストールした場合、
単純にPATH環境変数に各50個分ごとに実行ファイルがあるディレクトリまでのフルパスを追加する必要があります。
こうなると、PATHにいちいち追加するのも面倒ですし、その上PATH環境変数の文字数制限も気になってきます。
※環境にもよりますが、2,000字を超えると挙動が不安定になる可能性が出てくるそうです。[^1]

[^1]: PATH環境変数の文字数制限におけるIntel社の良記事はこちらです。https://software.intel.com/en-us/articles/limitation-to-the-length-of-the-system-path-variable

そこでScoopは`~\scoop\shims`フォルダをPATHに登録し、
そこに各Scoopアプリの実行ファイルを実行するための実行ファイルを置くことで
各アプリごとにPATHが増えてしまう現象を防いでいます。
（説明分かりづらくてすみません）

ただ、この仕組みの副作用として複数のScoopアプリが同じ実行ファイル名を持っていた場合、
（例えば、git-bash.exeは「git」と「git-with-openssh」で持っています）
whereコマンド等で確認してもshims配下の実行ファイル名が表示されるだけで
どのScoopアプリの実行ファイルが実行されるのか把握することができません。

こういった問題を解決するために`scoop which`をすることで以下のように解消することができます。

```powershell:例
# 普通にwhereコマンドなどを使った場合、~\scoop\shimsフォルダ配下のパスになります。
# これでは、どのScoopアプリの実行ファイルなのか区別することができません。
cmd /c where git-bash
C:\Users\xxxxx\scoop\shims\git-bash.exe

# scoop whichを使うことでどのScoopアプリのgit-bashかを区別することができます。
scoop which git-bash
#=>~\scoop\apps\git-with-openssh\current\git-bash.exe

# Scoopアプリ以外でもLinuxのwhichコマンドとして使用可能。
scoop which powershell
#=>C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe
```

# reset

インストール済みのScoopアプリを再設定するためのコマンドです。

```powershell:構文
scoop reset <app>
```

このコマンドはけっこう地味スゴです。
やることはインストール時に作成される`~\scoop\shims`配下の実行ファイルの再作成や
PATHやその他の環境変数を再度設定をするだけですが、これを活用することにより
Scoopアプリのバージョンの切り替えがコマンド一発でできるようになります。（オォー）

例えば、Scoopで「php56」「php73」をインストールした場合、
シェルから実行できるphp.exeは「php56」か「php73」のどちらか一方だけになります。

もし、PHP7.3系がPATHに通っているときに、PHP5.6系であるphp56のphp.exeに切替えたい場合は、
`scoop reset php56`とするだけでPHP5.6系に切り替えることができるのです。

```powershell:例
# php bucketをローカルに追加
scoop bucket add php
# php56, php73 をインストール
scoop install php56 php73

php --version
#=>PHP 7.3.7 (cli) (built: Jul  3 2019 14:34:10) ( ZTS MSVC15 (Visual C++ 2017) x64 )
#=>Copyright (c) 1997-2018 The PHP Group
#=>Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies

# PHP5.6系へ切り替える
scoop reset php56
#=>Resetting php56 (5.6.40).
#=>Linking ~\scoop\apps\php56\current => ~\scoop\apps\php56\5.6.40
#=>Creating shim for 'php'.
#=>WARN  Overwriting shim to php.exe installed from php73

php --version
#=>PHP 5.6.40 (cli) (built: Jan  9 2019 15:10:36)
#=>Copyright (c) 1997-2016 The PHP Group
#=>Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
```

# checkup

Scoopを使用する上で致命的な問題点がないかを診断するコマンドです。

```powershell:構文
scoop checkup
```

具体的には以下の診断処理が実施されます。

診断観点：

<dl>
  <dt>１．Scoopのインストール中にWindows Defenderとの競合が発生しないか？</dt>
  <dd>Windows Defenderのスキャンと競合が発生した場合、著しくインストールの速度が遅くなる可能性があるため、<br>
<code>~\scoop</code>配下にスキャン処理が走らないように除外設定することが推奨されているようです。<br><br></dd>
  <dt>２．Main Bucketがローカルに追加されているかどうか？</dt>
  <dd>こちらは歴史的な背景で、Scoopは最近までScoop自身とMain Bucketが同じリポジトリで管理されていたのですが、<br>
より運用しやすいようにリポジトリを分割する対応が入ったため、Main Bucketが別リポジトリとなりました。<br>
そのため、古いScoopをまだupdateせずに使っているユーザが正常にScoopを使用できないと困るため追加されている項目となります。<br><br></dd>
  <dt>３．260文字のファイルパスの制限が解除されているか？</dt>
  <dd>通常時は<code>C:\Program Files</code>配下にインストールするアプリを<code>~\scoop\apps</code>にインストールすることになるので、<br>
本来であれば問題ないがScoopだとファイルパスが長くなるため正常に動作できない問題を事前に指摘するのが目的のようです。<br><br></dd>
  <dt>４．Scoopがインストール時に使用している解凍ツールがインストール済みであるか？</dt>
  <dd>基本はScoopをインストールするときやその解凍ツールが必要となるScoopアプリを<br>
インストールするタイミングで自動でインストールされますが、<br>
何らかの理由でそうならない状況が発生した場合を考慮して診断内容に入っているようです。<br>
現状では、7zip, Innounp, WiX ToolSetのインストール状況がチェックされます。<br><br></dd>
  <dt>５．Scoopがインストール先に使っているドライブがNTFSでフォーマットされているか？</dt>
  <dd>普通のWindows環境であれば、たぶん、そう問題起きないです。<br><br></dd>
</dl>

```powershell:例
# Scoopの診断処理を実施
scoop checkup
#=>WARN  LongPaths support is not enabled.
#=>You can enable it with running:
#=>    Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1
#=>WARN  Found 1 potential problem.

# 警告で指示されたコマンドを実行。
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1

# 再診断
scoop checkup
#=>No problems identified!
```

# おわりに

第2回の解説は以上となります。

Scoopを使い始めて2年近くは経っていると思いますが、まだまだ知らないことが多いことに気づかされます。
次回で最後になりますが、今度はもっと使用する機会がなかったコマンド達なので、
より多くのことを知る機会になれば幸い。