◆ /etc/profile で /usr/sbin にパスを通してる
◆ zsh だと /etc/zprofile で /etc/profile をロードしてる
◆ fish は /etc/profile をロードしないので通ってない

ip コマンドがみつからない

IP アドレスを調べようと ip コマンドを使ったら

> ip a
fish: Unknown command 'ip'

コマンドが見つからないみたいです
ip コマンドってデフォルトじゃ使えないんだっけ? と思いながらなんとなく root ユーザで ip コマンドを使ったら

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
(略)

あれ?使えてます
どうして??

sbin

実行ファイルの場所を見てみると /usr/sbin の中でした
直接実行してみると

> /usr/sbin/ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
(略)

実行できてます
ということは パスが通ってないみたいです

> echo $PATH
/usr/local/bin /usr/bin
# echo $PATH
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin

root ユーザだと sbin もありますが 一般ユーザだと sbin がありません
そういうものでしたっけ??

いつも一般ユーザで ip コマンド使ってたはず と思って別の環境につないで試してみると 普通に使えました

fish

自分で sbin にパスを通したりはしてないと思いますし もともと通ってたように思います
どっちも fedora なのですが 22 くらいからアップグレード続けているものと 28 を新規でインストールしたものという違いがあります
この間で何か変わったのでしょうか?

そういえば shell も違って パスが通ってない方は fish に変更していたのでした
OS というより shell のほうが原因になりそうです

パスが通ってる環境で sbin がどこで設定されてるのかを見てみました
自分で設定した覚えがないだけあって 普段触りそうなファイルでは PATH を書き換えていません
分かりづらかったのですが zsh の /etc/zprofile で sbin が追加されていました

[user87z@fedora]~% cat /etc/zprofile
#
# /etc/zprofile and ~/.zprofile are run for login shells
#

PATH="$PATH:$HOME/bin"
export PATH

_src_etc_profile()
{
# Make /etc/profile happier, and have possible ~/.zshenv options like
# NOMATCH ignored.
#
emulate -L ksh

# source profile
if [ -f /etc/profile ]; then
source /etc/profile
fi
}
_src_etc_profile

unset -f _src_etc_profile

zprofile では

source /etc/profile

これを実行しています
/etc/profile をみると

[user87z@fedora]~% cat /etc/profile
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}

# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
fi

という部分があって /usr/sbin と /usr/local/sbin を PATH に追加しています
root かどうかで追加後の並びを変えるのと 重複しないようにすでにない場合のみ追加するためにこんな方法になってるようです

fish では /etc/profile を読み込まないので sbin が追加されてない ということみたいです
fish はいろいろ記法が違うので 単純にシェルスクリプトを実行するとエラーばっかりになりますからね
必要なら自分で fish の書式で fish の設定ファイルに書いてということでしょう

export PATH="$PATH:/usr/sbin"

順番や重複確認を気にしなくてもよかったので単純にこうしました

おまけ1: fish の環境変数設定

fish って環境変数の代入構文も export コマンドもないから set を使わないとダメ と聞いた覚えがあるのですが 普通に export と = 代入で動きました
ちょっと試してみると

user@fedora02 ~> export FOO="/home"
user@fedora02 ~> BAR="/home"
fish: Unsupported use of '='. In fish, please use 'set BAR /home'.

という感じで export のときは問題なく = が使えるみたいです
export を調べてみると

user@fedora02 ~> type export
export is a function with definition
# Defined in /usr/share/fish/functions/export.fish @ line 1
function export --description 'Set env variable. Alias for `set -gx` for bash compatibility.'
if not set -q argv[1]
set -x
return 0
end
for arg in $argv
set -l v (string split -m 1 "=" -- $arg)
switch (count $v)
case 1
set -gx $v $$v
case 2
if contains -- $v[1] PATH CDPATH MANPATH
set -l colonized_path (string replace -- "$$v[1]" (string join ":" -- $$v[1]) $v[2])
set -gx $v[1] (string split ":" -- $colonized_path)
else
set -gx $v[1] $v[2]
end
end
end
end

fish の関数で bash 互換になるように set -gx のエイリアスを作ってくれてるみたいです

おまけ2: root のときはできる理由

fish は sbin をロードしないと書きましたが root だとできています
これをどこでやってるのか調べてみると

user@fedora02 ~> cat /usr/share/fish/functions/__fish_complete_subcommand_root.fish

function __fish_complete_subcommand_root -d "Run the __fish_complete_subcommand function using a PATH containing /sbin and /usr/sbin"
set -lx PATH /sbin /usr/sbin $PATH ^/dev/null
__fish_complete_subcommand $argv
end

__fish_complete_subcommand_root.fish という関数で sbin を追加していました
root という名前が入ってるので root でのみ読み込まれるファイルみたいです