それなりブログ

とあるWebエンジニアのそれなりのブログ、JavaScript/Python/PHP/ゲーム作成 など

[Shell] $(cd $(dirname $0) && pwd) を理解する

CURRENT=$(cd $(dirname $0) && pwd) とは

これは CURRENT変数へスクリプトファイルのカレントディレクトリを格納する
シェルスクリプトのお便利ワンライナーです
#!/bin/sh
CURRENT=$(cd $(dirname $0) && pwd)
echo $CURRENT # -> どこから実行してもファイルの場所を返す

しかし、意味不明

最近これを知って便利に使っているんですが、自分のShellScrpit力の低さから理解不能でした
ということで、勉強することにしました

各要素の解説

特殊変数や記法などの整理です
$0 = スクリプトファイル名が入る
dirname 引数 = 引数文字列のディレクトリ部分だけを返す
&& = 左辺のコマンドがステータス0の正常終了なら右辺も実行する
$() = プログラミングの (式) と同じように式の分離や実行順序を明示するものみたい
pwd = カレントディレクトリを返す、説明不要だと思いますが

実行順序

こうみたいです
「cd でスクリプト設置場所へ移動した後に pwd でその場所を返している」というロジック
dirname $0
 ↓
cd $(dirname $0)
 ↓
cd $(dirname $0) && pwd
 ↓
CURRENT=$(cd $(dirname $0) && pwd)

疑問点

なんで cd をしているのにディレクトリが移動しないのでしょうか?

$( ~ ) 書式によるものっぽいのですが、これがわからないです。
解説サイトを絶賛募集中!

追記:$() は `(バッククォート)と同じでした

@paselaさんにご教授賜りました
以下、コメントの抜粋、詳細はコメント欄を参照願います
$(〜)はコマンド置換の構文。`〜`(バッククォート)と同じ。
バッククォートはエスケープとか入れ子がややこしくなるので普通は使わない。
コマンド置換はサブシェルで実行されるので、元の環境には影響を与えない。

4 Responses to “[Shell] $(cd $(dirname $0) && pwd) を理解する”

  • pasela より:

    $(〜)はコマンド置換の構文。`〜`(バッククォート)と同じ。
    バッククォートはエスケープとか入れ子がややこしくなるので普通は使わない。
    コマンド置換はサブシェルで実行されるので、元の環境には影響を与えない。
    man bashは長大すぎて怯むけど、目を通しておくと勉強になるぞ。
    以下のセクションに今回のことが書いてある。
    コマンド置換
    http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html#lbBA
    コマンド実行環境
    http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html#lbBU
    また、視点は違うけどこのページも参考になるね。
    bash で,サブシェルが起動される条件
    http://dsas.blog.klab.org/archives/50703133.html

  • kjirou より:

    あざーす!
    そうか man bash を読めばいいのかっ
    拝読させていただきます
    「サブシェル」と言われても「そんな単語あったなぁ」程度でピンと来てないので、能力が全く足りてないみたい

  • daiidai より:

    >なんで cd をしているのにディレクトリが移動しないのでしょうか?

    実行したシェルのプロセスで実行しているからそれをコマンドで実行したユーザーには影響がないのでは

  • kjirou より:

    シェルスクリプト内でも移動してなかったのが謎だったのですが、サブシェル内だとまたその中で別になるのだと知りました


コメントを残す

メールアドレスが公開されることはありません。