macOS の Wi-Fi をコマンドからオン・オフする【ターミナルやスクリプトからの WiFi の入れ直し】

> **MacBook Pro の本体の WiFi を、定期的に `cron` で再起動（オフ・オン）したい**のです。
> Mac の Mojave や Catalina で WiFi をオン／オフするコマンドはないのでしょうか。

## TL; DR

> `networksetup` ツールの `SetAirportPower` コマンドで Wi-Fi のオン・オフが可能です。

```shell-session:デバイスがen0の場合（要管理者権限）
$ networksetup -SetAirportPower en0 off
$ networksetup -SetAirportPower en0 on
```

- 2022/11/13 現在、macOS Monterey (OSX 12.6.1, Intel) でも動作することを確認しました。

## TS; DR

```bash:ヘルプ抜粋
Usage: networksetup -setairportpower <device name> <on off>
	Set Wi-Fi power for <device name> to either <on> or <off>.
```

```shell-session:デバイス名の確認方法
$ networksetup -listallhardwareports | grep -A 1 "Wi-Fi"
Hardware Port: Wi-Fi
Device: en0
```
```shell-session:WiFIオンオフ後にDHCPの更新をかける
$ networksetup -setairportpoweren0 off
$ sleep 5
$ networksetup -setairportpower en0 on
$ networksetup -setdhcp Wi-Fi
```

- あわせて読みたい：「[Mac の bash で現在の DNS サーバーなどのネットワーク設定を取得する](https://qiita.com/KEINOS/items/ae5446a96fafb84cb127)」 @ Qiita

### `networksetup`で利用可能なコマンド一覧

<details><summary>`networksetup` コマンド一覧</summary><div><br>

`networksetup -help` や `networksetup -printcommands` でも確認できます。また、どのコマンドもコマンド名から機能はピンと来ます。しかし、全部小文字なので読みづらいのです。そこで、一覧をキャメル・ケースにしてみました。ちなみにキャメルケースでも動作します。

```html
-ListNetworkServiceOrder
-ListAllNetworkServices
-ListAllHardwarePorts
-DetectNewHardware
-GetMACAddress <HardwarePort or Device Name>
-GetComputerName
-SetComputerName <Name>
-GetInfo <NetworkService>
-SetManual <NetworkService> <ip> <subnet> <Router>
-SetDHCP <NetworkService> [clientid]
-SetBootp <NetworkService>
-SetManualWithDHCPRouter <NetworkService> <ip> 
-GetAdditionalRoutes <NetworkService>
-SetAdditionalRoutes <NetworkService> [ <dest> <mask> <gateway> ]*
-Setv4off <NetworkService>
-Setv6off <NetworkService>
-Setv6Automatic <NetworkService>
-Setv6LinkLocal <NetworkService>
-Setv6Manual <NetworkService> <NetworkService> <Address> <prefixlength> <Router>
-Getv6AdditionalRoutes <NetworkService>
-Setv6AdditionalRoutes <NetworkService> [ <dest> <prefixlength> <gateway> ]*
-GetDNSServers <NetworkService>
-SetDNSServers <NetworkService> <DNS1> [DNS2] [...] 
-GetSearchDomains <NetworkService>
-SetSearchDomains <NetworkService> <Domain1> [Domain2] [...] 
-Create6to4Service <NewNetworkServiceName> 
-Set6to4Automatic <NetworkService> 
-Set6to4Manual <NetworkService> <RelayAddress> 
-GetFTPProxy <NetworkService>
-SetFTPProxy <NetworkService> <Domain> <Port number> <authenticated> <UserName> <password>
-SetFTPProxyState <NetworkService> <on off>
-GetWebProxy <NetworkService>
-SetWebProxy <NetworkService> <Domain> <Port number> <authenticated> <UserName> <password>
-SetWebProxyState <NetworkService> <on off>
-GetSecureWebProxy <NetworkService>
-SetSecureWebProxy <NetworkService> <Domain> <Port number> <authenticated> <UserName> <password>
-SetSecureWebProxyState <NetworkService> <on off>
-GetStreamingProxy <NetworkService>
-SetStreamingProxy <NetworkService> <Domain> <Port number> <authenticated> <UserName> <password>
-SetStreamingProxyState <NetworkService> <on off>
-GetGopherProxy <NetworkService>
-SetGopherProxy <NetworkService> <Domain> <Port number> <authenticated> <UserName> <password>
-SetGopherProxyState <NetworkService> <on off>
-GetSocksFirewallProxy <NetworkService>
-SetSocksFirewallProxy <NetworkService> <Domain> <Port number> <authenticated> <UserName> <password>
-SetSocksFirewallProxyState <NetworkService> <on off>
-GetProxyBypassDomains <NetworkService>
-SetProxyBypassDomains <NetworkService> <Domain1> [Domain2] [...] 
-GetProxyAutoDiscovery <NetworkService>
-SetProxyAutoDiscovery <NetworkService> <on off>
-GetPassiveFTP <NetworkService>
-SetPassiveFTP <NetworkService> <on off>
-GetAirportNetwork <Device Name>
-SetAirportNetwork <Device Name> <Network> [password]
-GetAirportPower <Device Name>
-SetAirportPower <Device Name> <on off>
-ListPreferredWirelessNetworks <Device Name>
-AddPreferredWirelessNetworkAtIndex <Device Name> <Network> <Index> <security type> [password]
-RemovePreferredWirelessNetwork <Device Name> <Network>
-RemoveAllPreferredWirelessNetworks <Device Name>
-GetNetworkServiceEnabled <NetworkService>
-SetNetworkServiceEnabled <NetworkService> <on off>
-CreateNetworkService <NewNetworkServiceName> <HardwarePort>
-RenameNetworkService <NetworkService> <NewNetworkServiceName>
-DuplicateNetworkService <NetworkService> <NewNetworkServiceName>
-RemoveNetworkService <NetworkService>
-OrderNetworkServices <Service1> <Service2> <Service3> <...>
-GetMTU <HardwarePort or Device Name>
-SetMTU <HardwarePort or Device Name> <value>
-ListValidMTURange <HardwarePort or Device Name>
-GetMedia <HardwarePort or Device Name>
-SetMedia <HardwarePort or Device Name> <subtype> [option1] [option2] [...]
-ListValidMedia <HardwarePort or Device Name>
-CreateVLAN <VLAN Name> <parent Device Name> <tag>
-DeleteVLAN <VLAN Name> <parent Device Name> <tag>
-ListVLANs
-ListDevicesThatSupportVLAN
-IsBondSupported <HardwarePort>
-CreateBond <bondName> <HardwarePort1> <HardwarePort2> <...>
-DeleteBond <bondDeviceName>
-AddDeviceToBond <HardwarePort> <bondDeviceName>
-RemoveDeviceFromBond <HardwarePort> <bondDeviceName>
-ListBonds
-ShowBondStatus <bondDeviceName>
-ListPPPoEServices
-ShowPPPoEStatus <Service Name ie., MyPPPoEService>
-CreatePPPoEService <Device Name ie., en0> <Service Name> <account Name> <password> [PPPoE Service Name]
-DeletePPPoEService <Service Name>
-SetPPPoEAccountName <Service Name> <account Name>
-SetPPPoEPassword <Service Name> <password>
-ConnectPPPoEService <Service Name>
-DisconnectPPPoEService <Service Name>
-GetCurrentLocation
-ListLocations
-CreateLocation <Location Name> [populate]
-DeleteLocation <Location Name>
-SwitchToLocation <Location Name>
-ListAllUserProfiles
-ListLoginProfiles <Service Name>
-EnableSystemProfile <Service Name> <on off>
-EnableLoginProfile <Service Name> <Profile Name> <on off>
-EnableUserProfile <Profile Name> <on off>
-Import8021xProfiles <Service Name> <file path>
-Export8021xProfiles <Service Name> <file path> <yes no>
-Export8021xUserProfiles <file path> <yes no>
-Export8021xLoginProfiles <Service Name> <file path> <yes no>
-Export8021xSystemProfile <Service Name> <file path> <yes no>
-SetTLSIdentityOnSystemProfile <Service Name> <file path> <passphrase>
-SetTLSIdentityOnUserProfile <Profile Name> <file path> <passphrase>
-DeleteSystemProfile <Service Name> 
-DeleteLoginProfile <Service Name> <Profile Name>
-DeleteUserProfile <Profile Name>
-Version
-Help
-PrintCommands
```

---

</div></details>

### 動作確認済み環境

- macOS: Mojave(10.14.3, 10.14.6), Monterey(12.6.1)
- `networksetup -version`: v1.8.3, v1.8.4
- `bash --version`: GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)

## 所感

正午と終業 10 分前に Mac の [`say` コマンド](https://www.google.com/search?q=site:qiita.com+mac+say+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)で音声アナウンス後、10 分経過したら [ WiFi ルーター（NEC）を再起動するシェル・スクリプト](https://qiita.com/KEINOS/items/caf86f05607ff31ec886#%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E6%AC%84%E3%81%AB%E3%82%B3%E3%83%94%E3%83%9A%E3%81%99%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88)の実行を `cron` で叩いています。

しかし、ルーター再起動後に**マシンやデバイスの WiFi を再起動（オン・オフ）しないと通信できなくなる**現象がボチボチ発生しました。WiFi 自体はつながっているようなのですが。

[「使ったことのあるネットワーク」（接続済アクセスポイント）の登録数が多い場合](https://qiita.com/KEINOS/items/33ad0fbc3b06843d9992#%E6%8E%A5%E7%B6%9A%E6%B8%88%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%81%A7%E4%B8%8D%E8%A6%81%E3%81%AA%E3%82%82%E3%81%AE%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%A6%E3%81%A9%E3%81%86%E3%81%8B)に、似たような現象が発生しやすいのは知っていました。しかし、そうでなくてもストリーミング視聴中に再起動されてリクエスト・タイムアウトが発生すると、顕著なようでした。また、動画の[バッファ](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%83%95%E3%82%A1#%E9%9B%BB%E5%AD%90%E8%A3%85%E7%BD%AE%E3%81%A7%E3%81%AE%E6%99%82%E9%96%93%E7%9A%84%E3%81%AA%E7%B7%A9%E8%A1%9D%E5%9B%9E%E8%B7%AF)が効いている間に動画を一時停止し、WiFi をオン・オフすれば割と大丈夫な印象です。

おそらく UDP などのストリーム受信中にルーターを再起動されると、クライアントが待ちぼうけを食らうようです。

そこで、WiFi ルーターの再起動をかけたら、本体の WiFi も入れ直す処理を入れようと思ったのですが、[「`mac` `wifi` `オン` `オフ` `コマンド`」を Qiita 記事に絞ってググって](https://www.google.com/search?q=site:qiita.com+mac+wifi+%E3%82%AA%E3%83%B3+%E3%82%AA%E3%83%95+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89&tbs=qdr:y)も、ここ１年以内に更新・作成された記事でタイトルからわかりやすいものがありませんでした。未来の自分のググラビリティとして。


## 参考文献

- 「[How to manage Wi-Fi with Terminal commands on OS X](https://www.techrepublic.com/article/pro-tip-manage-wi-fi-with-terminal-commands-on-os-x/)」@ TechRepublic
- P.44「Viewing or Changing Airport Settings | AirPort Settings | Chap 5 | [Mac OS X Server Command-Line Administration](https://www.apple.com/cn/server/docs/Command_Line.pdf)」@ Apple 公式 PDF マニュアル
- 「[Macで不調なWi-Fiに繋いでいるときに自動でON/OFFするスクリプト](https://qiita.com/ken1flan/items/eeff205870db1a5785b5)」@ Qiita
- 「[MacでWiFi通信が切れたときに通信デバイスを自動で再起動するやつ](https://qiita.com/yamashush/items/6c117391b9b7178977bb)」@ Qiita