---
title: "macOS path_helperと格闘する | grasys blog"
url: "https://blog.grasys.io/post/yusukeh/problem-macos-path-helper/"
description: "こんにちは長谷川です。 みなさんはmacOSでどのterminalを使っていますか？ 私は最近warpというterminalを使っています。 まだ個人的な使い方としてbashだからかあちこちかゆい感じなのですが、未来な感じのterminalで気に入っています。zshならめっちゃいいのかも といいつつも、補完機能が邪魔…"
---

# macOS path\_helperと格闘する

-   ![](/_astro/noicon.CTHOhNiB_1HMs6A.webp)[yusukeh](/authors/yusukeh/)
-   公開日：2022年9月21日
-   カテゴリー：[Tech](/categories/tech/)
-   タグ：[#macOS](/tags/macos/)

![macOS path\_helperと格闘する](/_astro/ogp.DS9N63CT_Z2sCJMI.webp)

こんにちは長谷川です。

みなさんはmacOSでどのterminalを使っていますか？  
私は最近[warp](https://www.warp.dev/)というterminalを使っています。  
まだ個人的な使い方としてbashだからかあちこちかゆい感じなのですが、未来な感じのterminalで気に入っています。zshならめっちゃいいのかも  
といいつつも、補完機能が邪魔で[tmux](https://github.com/tmux/tmux/wiki)ごしに触っています。（意味ないけど🤣）  
ただ[iTerm2](https://iterm2.com/)は安定してるし、[alacritty](https://github.com/alacritty/alacritty)はシンプルで良い。

[iTerm2](https://iterm2.com/)は言わずもがなですが、[alacritty](https://github.com/alacritty/alacritty)はconfigで設定するのでunixっぽくて好き。  
[warp](https://www.warp.dev/)は新しいし、ちょっとおもしろいので使ってます。飽きたら変えちゃうかもしれないけど。  
[Hyper](https://hyper.is/)はどうしても画面をキラキラバシバシさせちゃうので、Installもして設定もしてあるけど触らないようにしています😆  
もうちょっと[warp](https://www.warp.dev/)使ってみて飽きたら[alacritty](https://github.com/alacritty/alacritty)か[iTerm2](https://iterm2.com/)に戻ると思います・・・🤣  
ちなみにどうでもいいんだけど全部[dracula theme](https://draculatheme.com/)🧛‍♂️です。

## path\_helper

macOSでbashなりzshなりで[tmux](https://github.com/tmux/tmux/wiki)を使うとpath\_helper問題に直面します。  
他にもいっぱい局面があると思う。

[Google Search - path\_helper](https://www.google.com/search?q=path_helper)  
みんな似たような問題で悩んでるなぁ・・・

さて本題のmacosのpath\_helperですが\*\*/etc/profile\*\*を確認するとわかります。

Plain textcontent\_copy

```
bat -p /etc/profile
# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi
```

この3~5行目のこいつです。  
man（叩いてみたらあった😆）を見てみると・・・

Plain textcontent\_copy

```
man path_helper
path_helper(8)                                                     System Manager's Manual                                                    path_helper(8)

NAME
     path_helper – helper for constructing PATH environment variable

SYNOPSIS
     path_helper [-c | -s]

DESCRIPTION
     The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d and appends their contents to the PATH and
     MANPATH environment variables respectively.  (The MANPATH environment variable will not be modified unless it is already set in the environment.)

     Files in these directories should contain one path element per line.

     Prior to reading these directories, default PATH and MANPATH values are obtained from the files /etc/paths and /etc/manpaths respectively.

     Options:

     -c      Generate C-shell commands on stdout.  This is the default if SHELL ends with "csh".

     -s      Generate Bourne shell commands on stdout.  This is the default if SHELL does not end with "csh".

NOTE
     The path_helper utility should not be invoked directly.  It is intended only for use by the shell profile.

Mac OS X                                                               March 15, 2007                                                               Mac OS X
```

**/etc**配下のファイルを読み込んで**PATH**と**MANPATH**を上書きしてきます。  
**/etc**配下の読み込むファイルは以下です。

> [https://github.com/sharkdp/bat](https://github.com/sharkdp/bat)  
> A _cat(1)_ clone with syntax highlighting and Git integration.
> 
> [bat](https://github.com/sharkdp/bat)はcatコマンドの進化版みたいなやつです。自分のmacosの中では自分でどうにかできるんでfunctionでcatを上書き（乱暴🤣）して使ってます。（お仕事の環境ではしてはいけません）
> 
> [https://github.com/sharkdp/bat](https://github.com/sharkdp/bat)

Plain textcontent\_copy

```
yusukeh@yusuke-mbp ~ bash ❯ fd paths /etc/
/etc/manpaths
/etc/manpaths.d/
/etc/paths
/etc/paths.d/
```

> [https://github.com/sharkdp/fd](https://github.com/sharkdp/fd)  
> `fd` is a program to find entries in your filesystem. It is a simple, fast and user-friendly alternative to [`find`](https://www.gnu.org/software/findutils/). While it does not aim to support all of `find`’s powerful functionality, it provides sensible (opinionated) defaults for a majority of use cases.
> 
> fdもbatと同じでfindの進化版。  
> めっちゃ高速。ちょっと正規表現の書き方に癖があるかもだけど悪くないしシンプルで好き。  
> ちょっとignoreされてるものとの関連でひっかかりが悪いことがあるので注意した方が良い。  
> findの使い方忘れそう🤣
> 
> [https://github.com/sharkdp/fd](https://github.com/sharkdp/fd)

例えば/etc/pathsと/etc/paths.d/\*は以下です。  
結論としては以下がPATHの先頭に強制的に追加されます・・・🤬

Plain textcontent\_copy

```
bat -p /etc/paths
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

bat -p /etc/paths.d/*
/Library/Apple/usr/bin
```

例えば私の**PATH**は以下です。（ちなみに私は対策済みです。）

Plain textcontent\_copy

```
yusukeh@yusuke-mbp ~ bash ❯ printenv PATH | sd ":" "\n"
/Users/yusukeh/rerun
/Users/yusukeh/mo
/Users/yusukeh/google-cloud-sdk/bin
/Users/yusukeh/rust/bin
/Users/yusukeh/anyenv/bin
/Users/yusukeh/anyenv/envs/tfenv/bin
/Users/yusukeh/anyenv/envs/rbenv/shims
/Users/yusukeh/anyenv/envs/rbenv/bin
/Users/yusukeh/anyenv/envs/pyenv/shims
/Users/yusukeh/anyenv/envs/pyenv/bin
/Users/yusukeh/anyenv/envs/plenv/shims
/Users/yusukeh/anyenv/envs/plenv/bin
/Users/yusukeh/anyenv/envs/nodenv/shims
/Users/yusukeh/anyenv/envs/nodenv/bin
/opt/homebrew/opt/gnu-getopt/bin
/opt/homebrew/opt/coreutils/libexec/gnubin
/opt/homebrew/bin
/opt/homebrew/sbin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/Library/Apple/usr/bin
```

[rerun](https://rerun.github.io/rerun/)、[mutache](https://github.com/tests-always-included/mo)、[google-cloud-sdk](https://cloud.google.com/sdk/)、[rustup](https://github.com/rust-lang/rustup)、[anyenv](https://github.com/anyenv/anyenv)、[homebrew](https://brew.sh/)が入ってるのがわかってなんか恥ずかしい・・・

> [https://github.com/chmln/sd](https://github.com/chmln/sd)  
> sd - s\[earch\] & d\[isplace\]  
> `sd` is an intuitive find & replace CLI.
> 
> sedの進化版です。sedの使い方忘れそう🤣
> 
> [https://github.com/chmln/sd](https://github.com/chmln/sd)

path\_helperを実行すると・・・

Plain textcontent\_copy

```
/usr/libexec/path_helper -sPATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/yusukeh/rerun:/Users/yusukeh/mo:/Users/yusukeh/google-cloud-sdk/bin:/Users/yusukeh/rust/bin:/Users/yusukeh/anyenv/bin:/Users/yusukeh/anyenv/envs/tfenv/bin:/Users/yusukeh/anyenv/envs/rbenv/shims:/Users/yusukeh/anyenv/envs/rbenv/bin:/Users/yusukeh/anyenv/envs/pyenv/shims:/Users/yusukeh/anyenv/envs/pyenv/bin:/Users/yusukeh/anyenv/envs/plenv/shims:/Users/yusukeh/anyenv/envs/plenv/bin:/Users/yusukeh/anyenv/envs/nodenv/shims:/Users/yusukeh/anyenv/envs/nodenv/bin:/opt/homebrew/opt/gnu-getopt/bin:/opt/homebrew/opt/coreutils/libexec/gnubin:/opt/homebrew/bin:/opt/homebrew/sbin"; export PATH;MANPATH="/usr/share/man:/usr/local/share/man:/opt/homebrew/opt/coreutils/libexec/gnuman:/opt/homebrew/share/man"; export MANPATH;
```

もうなんとなくわかって頂けると思うんだけど・・・  
path\_helperが動いた後のPATHはこうなる。

Plain textcontent\_copy

```
/usr/libexec/path_helper -s | rg ^PATH | sd "PATH=|; export PATH;|\"" "" | sd ":" "\n"
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/Library/Apple/usr/bin
/Users/yusukeh/rerun
/Users/yusukeh/mo
/Users/yusukeh/google-cloud-sdk/bin
/Users/yusukeh/rust/bin
/Users/yusukeh/anyenv/bin
/Users/yusukeh/anyenv/envs/tfenv/bin
/Users/yusukeh/anyenv/envs/rbenv/shims
/Users/yusukeh/anyenv/envs/rbenv/bin
/Users/yusukeh/anyenv/envs/pyenv/shims
/Users/yusukeh/anyenv/envs/pyenv/bin
/Users/yusukeh/anyenv/envs/plenv/shims
/Users/yusukeh/anyenv/envs/plenv/bin
/Users/yusukeh/anyenv/envs/nodenv/shims
/Users/yusukeh/anyenv/envs/nodenv/bin
/opt/homebrew/opt/gnu-getopt/bin
/opt/homebrew/opt/coreutils/libexec/gnubin
/opt/homebrew/bin
/opt/homebrew/sbin
```

おい、待てよ！！ってなる・・・  
まあわかる。正常に動作するためにってのはよく分かる。  
だけどちょっとこれはちょっと・・・

先頭に追加が良くないと思うんだよな  
状況次第では環境変数が最初と最後にあったりとかするし・・・  
system系のやつがあちこちにあるんだとしたら、staticなpathで実行するようにして貰って、Userの自由度を上げてほしいなぁ  
保守性がってのはわかるけど・・・

Twitterとかみてると、/etcに追記しろって書いてる人がいる。  
macosは/etcが/private/etcにsynlinkされてるから良いっちゃ良い。  
あと、まあ自分で責任取れって話だろうからそれでいいんだろうけど乱暴だなと・・・  
個人的には/etcにごりっと個人的な設定を入れるのは抵抗が・・・linuxとかで使いにくくなるし・・・  
あと/etc/paths.dに配置しても現状のPATH踏襲された上で新たにPATHが追加されるだけなんで、解決にはならない。

どうでもいいんだけど  
昔、shellscriptでコマンドはフルパスで書けってよく怒られたし怒った思い出が・・・🤣  
そんでもって環境に手を付けられないポリシーの前提条件でSolaris, FreeBSD, Linuxでそれぞれバージョンも違ってて異なる環境でも動くshellscriptを書くって大変なことしてたなぁ・・・

## 解決策

[https://github.com/yb66/path\_helper](https://github.com/yb66/path_helper)

探してたらこんなの作ってる人がいて見つけた。  
ちょっと使ってみよう。

Plain textcontent\_copy

```
cd
test ! -d local/src && mkdir -p local/src
cd local/src
git clone https://github.com/yb66/path_helper.git
cd path_helper

exe/path_helper --help
Usage: path_helper.rb [options]
    -p, --path [PATH]                To get a completely fresh PATH pass an empty string or nothing at all (the default).
                                       To append something to the generated path pass the current path, or a path you wish appended.
    -m, --man [MANPATH]              Run for man pages but perhaps read `man manpages` first
                                       See `path' instructions for argument options.
    -f, --dyld-fram [DYLD]           DYLD_FALLBACK_FRAMEWORK_PATH env var
                                       See `path' instructions for argument options.
    -l, --dyld-lib [DYLD]            DYLD_FALLBACK_LIBRARY_PATH env var
                                       See `path' instructions for argument options.
    -c, --c-include [C_INCLUDE]      C_INCLUDE_PATH env var
                                       See `path' instructions for argument options.
        --pc [PKG_CONFIG_PATH]       PKG_CONFIG_PATH env var
                                       See `path' instructions for argument options.
    -q, --quiet                      Quiet, no output
    -d, --debug                      Debug mode, even more output
        --setup                      Set up directory structure, add specific switches
                                       (see `--etc` `--lib` `--config`)
                                       if specific setups required.
                                       Else --setup own its own will do all of them.
        --dry-run                    Use in conjuction with --setup to see what would happen if you ran it.
        --[no-]etc                   This has two applications:
                                       1. In combination with any of:
                                         `--path`, `--man`, `--dyld-fram`, `--dyld-lib`, `--c-include`, `--pc`
                                         will add/remove it from consideration for building the path.
                                       2. When combined with --setup will set up /etc/paths..., erm, etcetera.
                                       The default is for it to be included.
        --[no-]lib                   Adds ~/Library/Paths to the search/build path
                                       Included by default on a Mac.
                                       See `--etc` for more.
        --[no-]config                Adds ~/.config/paths
                                       Included by default on Linux.
                                       See `--etc` for more.
        --version                    Print version
    -h, --help                       Show this message
```

### \--dry-run –setup –no-etc –no-lib –config

Plain textcontent\_copy

```
exe/path_helper --dry-run --setup --no-etc --no-lib --config
Created /Users/yusukeh/.config/paths/c_include_paths.d
Created /Users/yusukeh/.config/paths/c_include_paths
Created /Users/yusukeh/.config/paths/dyld_fallback_framework_paths.d
Created /Users/yusukeh/.config/paths/dyld_fallback_framework_paths
Created /Users/yusukeh/.config/paths/dyld_fallback_library_paths.d
Created /Users/yusukeh/.config/paths/dyld_fallback_library_paths
Created /Users/yusukeh/.config/paths/manpaths.d
Created /Users/yusukeh/.config/paths/manpaths
Created /Users/yusukeh/.config/paths/pkg_config_paths.d
Created /Users/yusukeh/.config/paths/pkg_config_paths
Created /Users/yusukeh/.config/paths/paths.d
Created /Users/yusukeh/.config/paths/paths

# Put this in your ~/.bashrc or your ~/.zshenv
if [ -x /Users/yusukeh/local/src/path_helper/exe/path_helper ]; then
  export C_INCLUDE_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -c)
  export DYLD_FALLBACK_FRAMEWORK_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper --dyld-fram)
  export DYLD_FALLBACK_LIBRARY_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper --dyld-lib)
  export MANPATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -m)
  export PKG_CONFIG_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -pc)
  export PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -p)
fi
```

こうすれば~/.config配下つまりXDG\_CONFIG\_HOMEに配置される。  
\--etcは/etc配下だし、–libは~/Library配下だから嫌（めっちゃ個人的な感想だけど😅）  
/etcと~/Libraryと~/.config全部有効化するのは意味ないのでやめたほうが良いかな  
そもそもsystem-wideな設定は/etc/paths, /etc/paths.d, /etc/manpaths, /etc/manpaths.dにあるし、User Fieldでは~/Libraryか~/.configのどちらかのひとつで良いね。  
実際にsetupするなら–dry-runを取って実行すればconfigのディレクトリツリーを構成してくれる。

### config map

| Environment | config & config directory |
| --- | --- |
| PATH | ~/.config/paths/paths ~/.config/paths/paths.d |
| MANPATH | ~/.config/paths/manpaths ~/.config/paths/manpaths.d |
| C_INCLUDE | ~/.config/paths/c_include_paths ~/.config/paths/c_include_paths.d |
| PKG_CONFIG_PATH | ~/.config/paths/pkg_config_paths ~/.config/paths/pkg_config_paths.d |
| DYLD_FALLBACK_LIBRARY_PATH | ~/.config/paths/dyld_fallback_library_paths ~/.config/paths/dyld_fallback_library_paths.d |
| DYLD_FALLBACK_FRAMEWORK_PATH | ~/.config/paths/dyld_fallback_framework_paths ~/.config/paths/dyld_fallback_framework_paths.d |

configに直接書くよりかは、config directoryに対象の環境変数のを書いて対応した方が良さげかな？

README.mdみてると/usr/local/libexec配下に入れるとか~/bin配下にいれるみたいな感じだけどマニュアルで叩くものじゃないのでもうちょいどかしといた方が良い気はする。  
まあ好みの問題だし好きにすれば良いかな

### .bashrc

.bashrcに–setupで出力されたものを貼り付ければ  
関係する環境変数に関しては設定でmacos標準のpath\_helperに影響を受けず再構成できるようになる。  
下記のは自分のmacosの環境とUserのものなのでこのまま貼り付けちゃダメです。

Plain textcontent\_copy

```
# Put this in your ~/.bashrc or your ~/.zshenv
if [ -x /Users/yusukeh/local/src/path_helper/exe/path_helper ]; then
  export C_INCLUDE_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -c)
  export DYLD_FALLBACK_FRAMEWORK_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper --dyld-fram)
  export DYLD_FALLBACK_LIBRARY_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper --dyld-lib)
  export MANPATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -m)
  export PKG_CONFIG_PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -pc)
  export PATH=$(ruby /Users/yusukeh/local/src/path_helper/exe/path_helper -p)
fi
```

### ex) PKG\_CONFIG\_PATH & HOMEBREW

PKG\_CONFIG\_PATHがあるからpkg-configファイルがあることが前提だけど  
/opt/homebrew/lib/pkgconfigにパス通したりはこんな感じでできる。

Plain textcontent\_copy

```
echo /opt/homebrew/lib/pkgconfig >> ~/.config/pkg_config_paths.d/10-homebrew
```

先頭の数字は読み込ませたい順番

## 感想

CFLAGS, LDFLAGSとかも対応してるといいなとは思う。  
自分は環境をぐりっと調査して.bashrcを自動生成している。  
自前で似たような処理を書いて、/etc/profile読み込んだ後でも.bashrcで改めて初期化する形で対応してる。  
さっき紹介したのはrubyだけどオレのはbash。  
bashなだけあってそれなりに苦労😂

/etc/paths, /etc/paths.d, /etc/manpaths, /etc/manpaths.d読み込んだ後で  
以下を読み込んで順番通りに環境変数を整理してexportする。  
事前の環境変数は破棄して再構成してる。

Plain textcontent\_copy

```
cd .config/path_helper && exa --tree
.
├── c_include_paths
├── c_include_paths.d
├── dyld_fallback_framework_paths
├── dyld_fallback_framework_paths.d
├── dyld_fallback_library_paths
├── dyld_fallback_library_paths.d
├── dyld_library_paths
├── dyld_library_paths.d
├── include_paths
├── include_paths.d
│  ├── 09-usr_local
│  └── 10-homebrew
├── ld_library_paths
├── ld_library_paths.d
├── lib_paths
├── lib_paths.d
│  ├── 09-usr_local
│  └── 10-homebrew
├── manpaths
├── manpaths.d
│  ├── 09-usr_local
│  └── 10-homebrew
├── paths
├── paths.d
├── pkg_config_paths
└── pkg_config_paths.d
   └── 10-homebrew
```

> [https://github.com/ogham/exa](https://github.com/ogham/exa)  
> [exa](https://the.exa.website/) is a modern replacement for _ls_.
> 
> lsの進化版でHack Nert Fontでiconとかつけられる。おしゃれにしたいならこれ😆
> 
> [https://github.com/ogham/exa](https://github.com/ogham/exa)

みなさんはどう対応してますか？

## この記事を書いた人

[![](/_astro/yusukeh.BvUd2yKE_1mQ6Fp.webp)](/authors/yusukeh/)

### [yusukeh](/authors/yusukeh/)

Fly high. Think deep. Move fast. Go far.🦅

-   [X](https://x.com/yusukeh "X")
-   [GitHub](https://github.com/yusukeh "GitHub")
-   [Medium](https://medium.com/@yusukeh "Medium")
-   [Facebook](https://www.facebook.com/yusuke.exzm "Facebook")
-   [Instagram](https://www.instagram.com/yusukehasegawa/ "Instagram")
-   [LinkedIn](https://www.linkedin.com/in/hasegawa-yusuke-091b4164/ "LinkedIn")

[プロフィールと記事一覧](/authors/yusukeh/)
