$(cd $(dirname $0)/.. && pwd) と $(cd $(dirname $0) && pwd) の違い

投稿者: Anonymous

質問背景

$(cd $(dirname $0)/.. && pwd)

についてネット検索してみたら、

$(cd $(dirname $0) && pwd)

に関するページが見つかりました

質問

  • 両者の違いを教えてください
  • /.. に特別な意味はある?

最終的に知りたいこと

$(cd $(dirname $0)/.. && pwd)

は、どういう意味でしょうか? 多分、どのような環境でも動作するように設定していると思うのですが…

解決

最初に質問に答えると次のようになります。

  • $(cd $(dirname $0) && pwd) … 実行中のスクリプトがあるディレクトリの絶対パス (/ で始まるパス) 文字列
  • $(cd $(dirname $0)/.. && pwd) … 実行中のスクリプトがあるディレクトリの親ディレクトリの絶対パス文字列

ここで使われているシェル変数やコマンド、構文の意味は次のとおりです。

  • $0 は実行中のスクリプトのパス (bashsh に渡された引数そのもの) を表します。
  • dirname は引数で与えたパス文字列のディレクトリ部分を返すコマンドです。
  • pwd はカレントディレクトリを絶対パスで返すコマンドです。
  • $( ... ) はシェルで ... を実行した結果 (標準出力) の文字列に置き換えられます。

一般に $(cd DIR && pwd) は、ディレクトリ DIR (相対パスを含む) の絶対パスを取得するためのポータブルな方法と考えられます。

実際に実行してみるのが理解が早いでしょう。次のようなファイル script.sh をいろんな場所に置いて実行してみてください。

#!/bin/sh
echo $0
echo $(dirname $0)
echo $(cd $(dirname $0) && pwd)
echo $(cd $(dirname $0)/.. && pwd)

/tmp/script.sh に置いて実行した場合は次のようになります。

$ bash /tmp/script.sh 
/tmp/script.sh
/tmp
/tmp
/

ポイントは bash にスクリプトとして相対パスを指定して実行したときです。

$ cd /tmp
$ bash script.sh 
script.sh
.
/tmp
/

相対パスが渡されても pwd により絶対パスが得られていることがわかります。

また pwd はシェルが $PWD で保持する「論理的な」カレントディレクトリを返します。次のようなシンボリックリンクを含むディレクトリに移動して実行してみるとそれがわかります。

$ ln -s . /tmp/dir
$ cd /tmp/dir/dir/dir/dir
$ bash script.sh 
script.sh
.
/tmp/dir/dir/dir/dir
/tmp/dir/dir/dir

script.sh の実体が置かれているディレクトリは /tmp ですが、 pwdcd で移動した論理的なカレントディレクトリ /tmp/dir/dir/dir/dir を返しています。シンボリックリンクの影響を排除した絶対パスを得るには pwd -P が使えます。

$ cd /tmp/dir/dir/dir/dir
$ pwd
/tmp/dir/dir/dir/dir
$ pwd -P
/tmp
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *