fishパス関連設定した時の備忘録

# なぜ書いたか
結局どの記事読みに行っても1回で終わらないし、いつも手順忘れるので。

ただ、最近この全訳！fishシェル普及計画[http://fish.rubikitch.com/](http://fish.rubikitch.com/)ってサイトが公式リファレンスを翻訳して、わかりやすく解説を書いてくれているので、下手にこの記事見るより確実かもしれない・・・

2022年7月追記：

POSIX互換のコマンドをfish互換のコマンドに置き換えて実行してくれる `bass` という便利なプラグインが登場したようです。これを入れて実行すればこの記事に書かれているようなことはせずとも済む気がします。

https://github.com/edc/bass

とはいえ、fishをガチ使いしていくのであれば環境変数の設定程度は自前でコマンドを入力してくほうがいいかもしれませんけどね。

# 手順
## パスの設定
`echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile`
と手順で、シェル上に入力を求められていた場合、`.bash_profile`に
`PATH="$HOME/.rbenv/bin:$PATH"'`
を書き込むよう求められている。この場合、fishでは下記のように叩けばいい。

```sh
set -U fish_user_paths $HOME/.rbenv/bin $fish_user_paths
```

fishでは.bash_profileと同等のfish.configが`~/config/fish/config.fish`にあるが、ここにbashやzshのノリで追加していくのは、せっかくfish上で再起動なしに即時反映できるfishのメリットを殺してる気がする。

構文的に、本来は `set -x fish_user_paths $HOME/.rbenv/bin $fish_user_paths` と書くが、 `fish_user_paths` はfishがデフォルトで持っているユニバーサル変数である為、 `-x` をわざわざ付ける必要が無いし、付けると起動毎にfish_user_pathsに無限に追記されていくので重くなってしまう。

なので、この書き方を直接シェル上で叩くとfish_user_pathsという便利なユニバーサル変数の配列にどんどん足していってくれるからわざわざconfigファイルに書き足す必要は無いというわけである(直接パス一覧をエディタで編集できないのは不便だけどね)

※2022年03月25日追記
最近 `fish_add_path` なる関数が追加されたおかげで、下記の様にコマンドを打つだけでpathが追加できます。

```sh
fish_add_path $HOME/.rbenv/bin
```

https://fishshell.com/docs/current/cmds/fish_add_path.html#cmd-fish-add-path

## 環境変数
`echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.bash_profile`
と手順で、シェル上に入力を求められていた場合、`.bash_profile`に
`export GOENV_ROOT="$HOME/.goenv"`
を書き込むよう求められている。この場合、fishでは下記のように叩けばいい。

```
set -Ux GOROOT $HOME/.goenv
```

## 環境変数削除
`cat $fish_user_paths`(cat xxxでxxxの中身見るコマンド。詳しくはググって)や`fish_config`を叩くと表示されるコンフィグGUIの中にある`Variables→fish_user_paths`で表示して、何番目の要素かを確認する。配列で管理されるので、基本消すときはインデックスを指定して叩く。

が、どうやらインデックスが0始まりではなく1始まりなので、11と13の間にあるパスである12をを0始まりだと思って指定して消そうとすると13が消えるみたいなことがよく起こるので気をつける。その消したいインデックスnの要素を `echo fish_user_paths[n]` して合ってるか確認するのが吉。

というわけで、消すときはこう。

```
set -e fish_user_paths[n]
```

環境変数(ここではhogeとする)を消すときはインデックス不要でそのまま

```
set -e hoge
```

## setのオプション
### -U
> Universal variables are variables that are shared between all the users' fish sessions on the computer. Fish stores many of its configuration options as universal variables. This means that in order to change fish settings, all you have to do is change the variable value once, and it will be automatically updated for all sessions, and preserved across computer reboots and login/logout.

全ユーザーで使いたい場合はこれ使う。ちなみに小文字の`-u`は下記の`-x`のコマンドと対になるエクスポートしないを意味する為注意。

### -x
> Variables in fish can be exported. This means the variable will be inherited by any commands started by fish. It is convention that exported variables are in uppercase and unexported variables are in lowercase.

ということで、エクスポート可能な変数に付ける。要するに環境変数化するものらしい。

## eval
goenv等の開発環境バージョン管理ツールをgit cloneで構築すると設定が必要になるもの。

`echo 'eval "$(goenv init -)"' >> ~/.bash_profile`
と手順で、シェル上に入力を求められていた場合、`.bash_profile`に
`eval "$(goenv init -)"`を書き込むよう求められている。この場合、fishでは下記のように叩けばいい。

```
echo 'eval (goenv init -)' >> ~/.config/fish/config.fish
```

ここではconfig.fishに直接書き足さなきゃだめなのでechoコマンドをそのまま使うが、もしvi等で直接config.fishを開いた場合は

```eval (goenv init -)```

を最下行に追記すればいい。

ちなみに、fishでは `$(...)` という書き方はサポートされないので、$を省いて書く

## 他bashやzshと違うが故の注意点

一部のシェルスクリプトが動かない。どっかからのシェルスクリプトのコピペを実行してエラーが出ることがある。これはfishがPOSIX非互換であるがゆえに、変数の指定方法等の細かな違いや、実装されていない関数や機能等が存在する事に由来する。そんなときは・・・

素直にbashやzshを起動して実行させましょう。fishのリファレンスを漁りながら関数を変換したり、スクリプトを実行するスクリプトを実装するよりかは一番手っ取り早い。

# 参考

- Fish Tutorial
[https://fishshell.com/docs/current/tutorial.html](https://fishshell.com/docs/current/tutorial.html)
- Fish Documentation
[https://fishshell.com/docs/current/index.html](https://fishshell.com/docs/current/index.html)
- 全訳！fishシェル普及計画-set:シェル変数の設定・一覧・消去・確認する6活用-
[http://fish.rubikitch.com/set/](http://fish.rubikitch.com/set/)