それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

bashでファイルパスの相対パスを得る(絶対パスの取得やパスの正規化も)/realpath利用

realpath で解決

bashスクリプトで2つのファイルパス間の相対パスを取ろうとすると、計算が大変です。

LinuxMacも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

基本的な相対パスの求めから

ディレクトリ Aからみたディレクトリ Bが欲しい時

$ 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)

割となんとでもなるね。