macOS には「決まった時刻にスクリプトを動かす」「ログイン時にプログラムを起動する」 「常駐させて動かし続ける」といった処理を担う launchd という仕組みが標準で入っている。 この launchd に「いつ・何を・どう動かすか」を伝えて操作するためのコマンドが launchctl で、設定は plist という XML ファイルに書く。

Linux の cron や systemd に近い役割だが、macOS では launchd がこれらをまとめて引き受けている。 自分で実際に使っていたところ、いくつかわかりにくい挙動で詰まった部分があった。そこで、launchd の基本から実際に詰まったところまでまとめて記録しておく。

本記事の内容は macOS Sequoia 15.7.7 で動作を確認している。

launchctl と launchd とは

launchd は macOS が起動するときに最初に立ち上がる、すべてのプロセスの親にあたる 管理プロセス。システムの起動処理、常駐サービス(デーモン)の管理、ユーザーがログインしたときの アプリ起動、定期実行のスケジューリングなどを一手に引き受けている。普段は意識しないが、Mac の中で 動いているバックグラウンド処理の多くはこの launchd が面倒を見ている。

launchctl は、その launchd に対して「このジョブを登録して」「今すぐ動かして」 「状態を見せて」と指示を出すためのコマンドラインツール。自分でジョブを追加したいときは、 やりたいことを plist ファイルに書き、それを launchctl で launchd に登録する、 という流れになる。

cron との違いも押さえておくとよい。cron は「定期実行」に特化しているが、launchd は定期実行に加えて 「ログイン時に1回だけ実行」「落ちたら再起動して常駐」「特定フォルダが変化したら実行」など、 起動のきっかけを幅広く指定できる。ログ出力先や環境変数も plist にまとめて書けるので、 cron より少し記述は多いが、その分こまかく制御できる。

LaunchAgent と LaunchDaemon の違い

launchd で動かすジョブには LaunchAgentLaunchDaemon の 2 種類があり、どちらにするかで「いつ・誰の権限で動くか」が変わる。最初はこの違いでつまずきやすいので、 先に整理しておく。

種類 動くタイミング 実行権限 向いている用途
LaunchAgent ユーザーがログインしている間 ログインユーザー 個人の定期処理、GUI を伴う処理、通知
LaunchDaemon OS 起動時から(ログイン不要) root(システム) 常駐サービス、全ユーザー共通の処理

個人で「毎日この時刻にスクリプトを回したい」という程度なら、まず LaunchAgent を 選んでおけばよい。画面に誰もログインしていない状態でも動かしたい、root 権限が必要、といった場合に LaunchDaemon を検討する。置き場所もこの種類によって変わる(後述の 配置場所を参照)。

plist の基本構造

plist(Property List)は macOS の設定ファイル形式で、launchd の設定も XML 形式の plist で書く。 中身は <key>(項目名)と、その値(<string><integer> など)のペアを <dict>(辞書)の中に並べていく構造になっている。 次は実用的な項目をひととおり入れた例で、各行にコメントで意味を添えている。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <!-- ジョブを識別する一意な名前(必須) -->
    <key>Label</key>
    <string>com.example.myjob</string>

    <!-- 実行するコマンドと引数。1要素目が実行ファイル -->
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/my-script.sh</string>
        <string>--option</string>
        <string>value</string>
    </array>

    <!-- 実行スケジュール(毎日9時0分) -->
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>

    <!-- 実行時のカレントディレクトリ -->
    <key>WorkingDirectory</key>
    <string>/usr/local/var/myjob</string>

    <!-- 環境変数を渡す -->
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/usr/local/bin:/usr/bin:/bin</string>
    </dict>

    <!-- 標準出力・標準エラーの書き出し先 -->
    <key>StandardOutPath</key>
    <string>/tmp/myjob.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/myjob.err</string>
</dict>
</plist>

値の型は決まったタグで表す。文字列は <string>、整数は <integer>、 真偽値は <true/> / <false/>、複数の値を並べる配列は <array>、入れ子の辞書は <dict> を使う。型を間違える (たとえば数値を <string> で書く)と読み込みに失敗するので、後述の plutil -lint で必ず確認する。

plist で使えるキー一覧(取りうる値)

launchd の plist で指定できる主なキーをまとめる。実際には LabelProgramArguments(または Program)さえあれば動くので、残りは 必要に応じて足していけばよい。

必ず/よく使うキー

キー 説明
Label 文字列 ジョブの一意な識別子(必須)。他と重複しなければ任意の文字列でよいが、慣習として逆ドメイン形式(com.example.myjob)にし、plist のファイル名とも揃える。
ProgramArguments 文字列の配列 実行するコマンドと引数。1 要素目が実行ファイルのパス、2 要素目以降が引数。コマンドは絶対パスで書く。
Program 文字列 実行ファイルのパスだけを指定する簡易版。引数が要らないとき用。ProgramArguments があればそちらが優先される。
RunAtLoad 真偽値 true でロードした瞬間に 1 回実行する。動作確認や、起動直後に走らせたい処理に使う。
StartInterval 整数(秒) 指定した秒数ごとに繰り返し実行する。例:3600 で 1 時間ごと。
StartCalendarInterval 辞書 / 配列 cron のように時刻・曜日を指定して実行する。詳細は次節
StandardOutPath 文字列 標準出力(コマンドの通常の出力)を書き出すファイルパス。
StandardErrorPath 文字列 標準エラー(エラーメッセージ)を書き出すファイルパス。失敗の原因調査に使うので入れておくとよい。
WorkingDirectory 文字列 スクリプトを実行する際のカレントディレクトリ。相対パスを扱うスクリプトで重要。
EnvironmentVariables 辞書 ジョブに渡す環境変数。launchd 経由では PATH が最小限になりがちなので、必要なら明示する。

起動制御・常駐に使うキー

キー 説明
KeepAlive 真偽値 / 辞書 true でプロセスが終了するたびに再起動(常駐用)。辞書で条件を絞れる(後述)。
Disabled 真偽値 true でジョブを無効化。load しても起動しない。
LaunchOnlyOnce 真偽値 true でロード中に一度だけ実行する。
ThrottleInterval 整数(秒) 連続再起動の最小間隔。デフォルトは 10 秒。短時間で何度も落ちるジョブの暴走を防ぐ。
ExitTimeOut 整数(秒) 停止シグナルを送ってから強制終了するまでの猶予。デフォルトは 20 秒。
ProcessType 文字列 スケジューラ上の優先度。Background / Standard / Adaptive / Interactive のいずれか。重い処理は Background にする。
Nice 整数(-20〜20) プロセスの nice 値(CPU 優先度)。数値が小さいほど優先される。
WatchPaths 文字列の配列 指定したパス(ファイル / フォルダ)に変更があると実行する。
QueueDirectories 文字列の配列 指定ディレクトリにファイルが存在する間、実行を繰り返す。フォルダ監視処理に使う。
StartOnMount 真偽値 true で、ボリュームがマウントされるたびに実行する。
UserName / GroupName 文字列 実行するユーザー / グループ。主に LaunchDaemon で「root 以外で動かしたい」ときに使う。
RootDirectory 文字列 chroot して実行するルートディレクトリ。
AbandonProcessGroup 真偽値 true で、親プロセス終了時に子プロセスを道連れにせず残す。

StartCalendarInterval のスケジュール指定

定期実行で中心になるのが StartCalendarInterval。中に時刻や曜日のフィールドを書き、 指定したフィールドが一致したときに実行される。書かなかったフィールドはワイルドカード (毎回マッチ)扱いになる。たとえば Minute だけ書けば「毎時その分」、 HourMinute を書けば「毎日その時刻」になる。

各フィールドの取りうる値は次のとおり。

フィールド 取りうる値 意味
Minute0〜59
Hour0〜23時(24時間制)
Day1〜31日(月の中の日付)
Weekday0〜7曜日。0 と 7 が日曜、1=月曜 … 6=土曜
Month1〜12

複数の時刻に実行したいときは、StartCalendarInterval を辞書ではなく辞書の配列にして並べる。 単純に「一定間隔ごと」でよければ StartInterval(秒数)の方が手軽。

<!-- 毎日 AM 9:30 -->
<key>StartCalendarInterval</key>
<dict>
    <key>Hour</key><integer>9</integer>
    <key>Minute</key><integer>30</integer>
</dict>

<!-- 毎週月曜 AM 10:00(Weekday は 0/7=日曜, 1=月曜 … 6=土曜) -->
<key>StartCalendarInterval</key>
<dict>
    <key>Weekday</key><integer>1</integer>
    <key>Hour</key><integer>10</integer>
    <key>Minute</key><integer>0</integer>
</dict>

<!-- 毎月1日 AM 0:00 -->
<key>StartCalendarInterval</key>
<dict>
    <key>Day</key><integer>1</integer>
    <key>Hour</key><integer>0</integer>
    <key>Minute</key><integer>0</integer>
</dict>

<!-- 1日に複数回(配列で並べる。9時と18時) -->
<key>StartCalendarInterval</key>
<array>
    <dict>
        <key>Hour</key><integer>9</integer>
        <key>Minute</key><integer>0</integer>
    </dict>
    <dict>
        <key>Hour</key><integer>18</integer>
        <key>Minute</key><integer>0</integer>
    </dict>
</array>

<!-- 一定間隔で繰り返す(StartInterval は秒数。3600=1時間ごと) -->
<key>StartInterval</key>
<integer>3600</integer>

注意:Mac がスリープしている時刻に予定があった場合、その回は飛ばされる(cron と同じ)。ただし launchd は復帰後に「逃した実行」を 1 回だけまとめて走らせる挙動があるので、起きていなかった分が 丸ごと消えるとは限らない。

KeepAlive で常駐させる

「スクリプトを動かし続けたい」「落ちても自動で立ち上げ直したい」という常駐用途では KeepAlive を使う。true にすると、プロセスが終了するたびに launchd が 再起動する。条件を絞りたいときは辞書で書く。

<!-- プロセスが落ちたら自動で再起動する(常駐用) -->
<key>KeepAlive</key>
<true/>

<!-- 条件つきの再起動(異常終了したときだけ再起動する) -->
<key>KeepAlive</key>
<dict>
    <key>SuccessfulExit</key>
    <false/>
</dict>

辞書で指定できる主な条件キーは次のとおり。

サブキー 意味
SuccessfulExit 真偽値 true なら正常終了後も再起動、false なら異常終了したときだけ再起動。
Crashed 真偽値 true でクラッシュ時に再起動する。
NetworkState 真偽値 true でネットワークが有効なときだけ起動する。
PathState 辞書 指定したパスが存在する/しない状態に応じて起動を制御する。

plist の配置場所

plist をどのディレクトリに置くかで、それが LaunchAgent になるか LaunchDaemon になるか、 誰の権限で・いつから動くかが決まる。個人利用なら ~/Library/LaunchAgents/ を使うのが基本。

ディレクトリ 種類 対象 実行ユーザー
~/Library/LaunchAgents/ Agent そのユーザーがログイン中 ログインユーザー
/Library/LaunchAgents/ Agent 全ユーザー(要管理者権限) ログインユーザー
/Library/LaunchDaemons/ Daemon システム全体(起動時から) root
/System/Library/... macOS 組み込み(触らない)

/System/Library/ 以下は OS 標準のジョブが入っている領域なので、自分のジョブを置いたり 中身を書き換えたりしない。自作のものは ~/Library/LaunchAgents/ か、root で動かしたいときだけ /Library/LaunchDaemons/ に置く。

はじめてのジョブを動かす手順

まずは確実に動く最小構成で一度通してみるのが理解の近道。次の plist を ~/Library/LaunchAgents/com.example.hello.plist として保存する。 ロードした瞬間に /bin/echo を 1 回実行し、結果を /tmp/hello.log に書き出すだけのジョブ。

plist ファイルは、フォルダが無ければ mkdir -p ~/Library/LaunchAgents で作ってから、 nano ~/Library/LaunchAgents/com.example.hello.plist(または VS Code などの好きなエディタ)で 新規作成し、次の内容を貼り付けて保存する。特別なツールは要らず、ただのテキストファイルとして書けばよい。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.hello</string>

    <key>ProgramArguments</key>
    <array>
        <string>/bin/echo</string>
        <string>hello launchd</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>StandardOutPath</key>
    <string>/tmp/hello.log</string>
</dict>
</plist>

保存したら、次の流れで動作を確認する。

# 1) フォルダが無ければ作る
mkdir -p ~/Library/LaunchAgents

# 2) 上の最小plistを com.example.hello.plist として保存
#    (Label と同じ名前にするのが慣習)

# 3) 文法チェック(OK が出れば書式は正しい)
plutil -lint ~/Library/LaunchAgents/com.example.hello.plist

# 4) ロード(RunAtLoad が true なのでロード時に1回実行される)
launchctl load ~/Library/LaunchAgents/com.example.hello.plist

# 5) 結果を確認
cat /tmp/hello.log

# 6) 後片付け(登録を解除する)
launchctl unload ~/Library/LaunchAgents/com.example.hello.plist

launchctl load は成功しても何も表示しない(無言で完了する)。エラーが出ていなければ 登録できているので、/tmp/hello.log に行が追記されているか確認する。書き込まれていれば成功。 ここまで通せれば、あとは ProgramArguments を自分のスクリプトに、RunAtLoadStartCalendarInterval に置き換えていくだけで定期実行に発展させられる。

基本コマンド(load / unload / list)

plist を配置したら、launchctl で launchd に登録(ロード)する。登録を外すのがアンロード。 状態確認や手動実行もこのコマンドから行う。

# ロード(plistをlaunchdに登録する)
launchctl load ~/Library/LaunchAgents/com.example.myjob.plist

# アンロード(登録を解除する)
launchctl unload ~/Library/LaunchAgents/com.example.myjob.plist

# 登録済みジョブの一覧を見る
launchctl list

# Label でしぼり込む
launchctl list | grep com.example

# スケジュールを待たずに今すぐ実行する
launchctl start com.example.myjob

# 実行中のジョブを止める
launchctl stop com.example.myjob

plist を編集したときは、一度 unload してから load し直さないと変更が反映されない 点に注意。load し直さずに中身だけ書き換えても、launchd は古い設定で動き続ける。

bootstrap / bootout とドメインの考え方

macOS 10.10 Yosemite 以降では、load / unload に代わる新しいコマンドとして bootstrap / bootout が用意されている。新しい macOS ではこちらが推奨で、 後述の SSH 経由の操作でも必要になる。

新コマンドの肝は「ドメイン」という考え方。launchd はジョブを、それが属する場所 (セッション)ごとに区切って管理しており、操作するときにどのドメインかを明示する。よく使うのは次の 2 つ。

  • gui/<uid> … GUI でログイン中のユーザーセッション。LaunchAgent はここ。<uid>id -u で得られる数値。
  • system … システム全体。LaunchDaemon はここ。
# bootstrap(load に相当・ドメインを明示する)
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.myjob.plist

# bootout(unload に相当)
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.example.myjob.plist

# ジョブの詳細な状態を見る(終了コード・実行状況など)
launchctl print gui/$(id -u)/com.example.myjob

# 今すぐ実行する(再起動つき)
launchctl kickstart -k gui/$(id -u)/com.example.myjob

kickstart -k はジョブを今すぐ起動するコマンドで、-k を付けると実行中の場合は 一度止めてから起動し直す。動作確認に便利。

⚠️ Desktop 配下のスクリプトが実行できない

実際に動かしたときにハマった点。まず、plist の ProgramArguments~/Desktop 配下のスクリプトを指定すると、ロードはエラーなく成功するのに、いざ実行される 時刻になっても何も起きないことがある。エラーも出ないので原因が分かりにくい。

<!-- ~/Desktop のスクリプトを呼び出す例 -->
<!-- ロードは成功するのに、実行されない/エラーも出ない -->
<key>ProgramArguments</key>
<array>
    <string>/Users/username/Desktop/myscript.sh</string>
</array>

原因は macOS Catalina(10.15)以降の TCC(Transparency, Consent, and Control)によるサンドボックス保護。 ~/Desktop~/Documents~/Downloads はアクセスに明示的な許可が 必要な保護対象フォルダになっており、GUI セッションの外で動く launchd はそのままではここを読めない。 結果として Operation not permitted になるか、何も表示されず静かに失敗する。

「システム設定 → プライバシーとセキュリティ → フルディスクアクセス」に launchctllaunchd を足しても解決しない。確実なのは、plist が参照するスクリプト本体を保護対象外の ディレクトリ(~/bin など)へ移すこと。

# 避けるべき場所(TCC の保護対象)
~/Desktop/myscript.sh
~/Documents/myscript.sh
~/Downloads/myscript.sh

# スクリプトを保護対象外へ移す
mkdir -p ~/bin
mv ~/Desktop/myscript.sh ~/bin/myscript.sh
chmod +x ~/bin/myscript.sh

# plist 側のパスも書き換える
<key>ProgramArguments</key>
<array>
    <string>/Users/username/bin/myscript.sh</string>
</array>

「実行ファイル」と「処理対象データ」を分けて考える

ここがいちばん分かりにくいところ。「Desktop が絡むと何もかも動かない」と思いがちだが、実際にダメなのは launchd が直接起動する実行ファイル(plist の ProgramArguments が指すスクリプト本体) が保護フォルダにある場合だけ。スクリプトが 処理対象として読み書きするデータファイル~/Desktop 配下にあること自体は問題にならない。

理由は、止まる場所が違うから。前者は launchd がスクリプトを起動する「入口」で保護に阻まれ、プロセスが 起動すらできない。後者はスクリプト本体が保護外にあるので起動は成功し、起動したプロセスが (LaunchAgent ならユーザーのログインセッション内・ユーザー権限で動くため)Desktop のファイルを 読み書きするのは通る。

構成 結果 理由
plist が指す実行ファイル本体~/Desktop 配下 ✗ 起動できない launchd が保護フォルダの実行ファイルを起動する入口で阻まれる(無言で失敗)
実行ファイルは保護外(~/bin 等)・処理対象データ~/Desktop 配下 ✓ 動く 起動は保護外なので成功し、その後のデータ読み書きはユーザー権限(LaunchAgent)で通る
# OK な構成:実行ファイルは保護外、処理対象データは Desktop 配下でもよい
~/bin/backup.sh            # ← launchd が起動するスクリプト本体(保護外に置く)

# backup.sh の中身(処理対象のデータは ~/Desktop でも動く)
#!/bin/bash
ls ~/Desktop/*.csv >> /tmp/backup.log   # Desktop のファイルを読む処理は通る

# plist が指すのは「スクリプト本体」。ここが保護外なら起動できる
<key>ProgramArguments</key>
<array>
    <string>/Users/username/bin/backup.sh</string>
</array>

補足:後者も TCC が厳しい環境やフルディスクアクセス未付与の場合は、データ側のアクセスが Operation not permitted で拒否されることがある。その場合は「システム設定 → プライバシーとセキュリティ → フルディスクアクセス」に、スクリプトを動かす実体 (ターミナルや /bin/bash など)を許可すると通るようになる。なお LaunchDaemon (root 実行)はユーザーの Desktop に対する権限が無いため、この構成でもデータ側で弾かれやすい。

⚠️ SSH からの操作で挙動が変わる

こちらも実際にハマった点、 SSH 経由の操作。SSH でリモートログインした状態で launchctl load を実行すると、手元のターミナルとは違う結果になることがある。

$ launchctl load ~/Library/LaunchAgents/com.example.myjob.plist
# → "Could not find domain for this service"
# → "Bootstrap failed: 5: Input/output error"
# → 何も起きない(無言で失敗)

これは前述のドメインが関係している。GUI ログインのセッションは gui/<uid>、SSH のセッションは user/<uid> という別ドメインで、 LaunchAgent は GUI セッション側に属する。SSH のドメインからは、GUI 側のジョブをそのまま 操作できないため、対象が見つからずエラーになる。

SSH から操作する場合は、bootstrap / bootout / printgui/<uid> を明示的に渡す。手元のターミナルで使っていた load を そのまま SSH 越しに打つとハマるので、SSH のときは新コマンド+ドメイン指定に切り替えると覚えておく。

# 自分の UID を確認する
id -u   # → 例: 501

# bootstrap / bootout は gui/<uid> ドメインを明示する
launchctl bootstrap gui/501 ~/Library/LaunchAgents/com.example.myjob.plist
launchctl bootout gui/501 ~/Library/LaunchAgents/com.example.myjob.plist

# 状態確認
launchctl print gui/501/com.example.myjob

# 今すぐ実行
launchctl kickstart -k gui/501/com.example.myjob

# それでも動かないとき:GUI セッションが存在するか確認する
who   # ログイン中のセッション一覧(console 行があれば GUI ログイン中)

それでも動かない場合は、そもそも GUI セッションが存在しない(誰も画面にログインしていない) ケースが考えられる。その場合は素直に LaunchDaemon(/Library/LaunchDaemons/ に置いて sudo launchctl bootstrap system ...)として root 権限で動かす方が確実。

デバッグ・ログ確認

想定どおり動かないときの調べ方。まず plutil -lint で plist の文法を確認し、次に launchctl list の終了コードを見る。さらに追うなら launchctl print で 詳細を、log コマンドで launchd 周りのログを見る。

# plist の文法チェック(まずこれ)
plutil -lint ~/Library/LaunchAgents/com.example.myjob.plist
# → OK: /Users/.../com.example.myjob.plist: OK

# 登録状態と終了コードを見る
launchctl list | grep com.example
# → -    78    com.example.myjob   ← 78 = エラーあり
# → -    0     com.example.myjob   ← 0  = 正常終了
# → 501  -     com.example.myjob   ← 数字 = 実行中の PID

# ジョブの詳細(最後の終了コード・パスなど)
launchctl print gui/$(id -u)/com.example.myjob

# launchd 関連のログをリアルタイムで見る
log stream --predicate 'subsystem == "com.apple.launchd"' --level debug

# 過去ログをさかのぼる(スクリプト名で絞り込み)
log show --predicate 'processImagePath contains "myscript"' --last 1h

launchctl list の出力は左から「PID・最後の終了コード・Label」の順。終了コードの主なものは次のとおり。

終了コード 意味
0正常終了
1一般的なエラー
78設定エラー(plist の記述ミスが多い)
127コマンド・スクリプトが見つからない(パスの誤り)
Operation not permitted権限エラー(TCC・Desktop 問題など)

つまずきやすいところ

  • plist を書き換えただけでは反映されない。unloadload(または bootoutbootstrap)でロードし直す。
  • 「ロード成功」と出ても、スクリプト本体が保護フォルダ(Desktop など)にあると静かに失敗する。エラーが出ないぶん気づきにくい。
  • plist 内のパスでは ~ が展開されない。~/bin/x.sh ではなく /Users/ユーザー名/bin/x.sh のように絶対パスで書く。
  • コマンドやスクリプトは絶対パスで書く。launchd 経由では PATH が最小限なので、python のような名前だけの指定は見つからないことがある。
  • SSH からは gui/<uid> を明示しないと操作できない。ローカルで動いたコマンドをそのまま持ち込むとハマる。
  • StartCalendarInterval はフィールドを書かないと「毎回」扱いになる。Minute を書き忘れると毎分実行になってしまう点に注意。

参考(一次情報)

各キーの正式な仕様や、ここで触れていないオプションを確認したいときは、macOS に標準で入っている man ページが一次情報として確実。ターミナルで次を実行すれば、その環境の launchd に対応した 正確な内容を参照できる。

man launchctl       # launchctl コマンドのリファレンス
man launchd.plist   # plist で指定できるキーの正式な仕様(型・取りうる値)
man launchd         # launchd 本体の説明

特に man launchd.plist は、本記事の「plist で使えるキー一覧」で 挙げた各キーの型・取りうる値・デフォルト挙動が正式に定義されている。記事と挙動が食い違う場合は、 手元の環境の man ページを優先してほしい。