realpath で解決
bashスクリプトで2つのファイルパス間の相対パスを取ろうとすると、計算が大変です。
LinuxもMacもrealpath は入ってないので、 apt/brew でいれる必要があります。
realpath のインストール
macOS の場合はhomebrew で GNU Linux coreutils をいれる
brew install coreutils
coreutilsのインストールは好き嫌いが別れるのですが、私はGNUコマンドでいいからガンガン入れてしまってます。
絶対パスの取得
realpath ../../../.bashrc
相対パスの取得
realpath --relative-to=/Users/takuya/.ssh /
ちょっとわかりにくいけど、/Users/takuya/.ssh
からみた /
の相対パスが出力される。
.
しか見えないときにわかりやすいかも
相対パスの取得の例
$ realpath --relative-to=. . .
下の階層を見た場合
/
から /tmp
を見た場合
$ realpath -s --relative-to=/ /tmp/ tmp
基本的な相対パスの求めから
$ realpath -s --relative-to=A B
ファイルA.txtからみたファイルB.txtへの相対パスが欲しい時
realpath --relative-to=$(dirname A.txt) B.txt
相対パスを求めるときは、 --relative-to
にディレクトリを入れるとわかる。
/var/www からみた /var/log
takuya@sites$ realpath --relative-to=/var/www /var/log ../log
/var/www/html からみた /var/log
$ realpath --relative-to=/var/www/html /var/log ../../log
うん、この感じいいね。
/var/www/html/index.php からみた /var/log
んん????
$ realpath --relative-to=/var/www/html/index.php /var/log ../../../log
ああ、ファイル名をエントリとして1段の下の階層に来てしまうね。
ファイルをいれるときは dirname を使うよね。
$ realpath --relative-to=$(dirname /var/www/html/index.php) /var/log ../../log
持っててよかった realpath
realpath を入れておくと便利ですよね。
realpath コマンドがない場合
そういう時もありますよね。
python の os を使う。
import os.path, sys; print os.path.relpath('A' ,'B')
ruby のpathnameを使う
require 'pathname' path = Pathname.new("/tmp/foo") base = Pathname.new("/tmp") path.relative_path_from(base)
割となんとでもなるね。