Bash で現在の作業ディレクトリをスクリプトのディレクトリに設定するにはどうすればよいですか? 質問する

Bash で現在の作業ディレクトリをスクリプトのディレクトリに設定するにはどうすればよいですか? 質問する

Bash スクリプトを書いています。現在の作業ディレクトリが常にスクリプトが配置されているディレクトリである必要があります。

デフォルトの動作では、スクリプト内の現在の作業ディレクトリは、スクリプトを実行するシェルのディレクトリになりますが、この動作は望ましくありません。

ベストアンサー1

要約

#!/bin/bash
cd "$(dirname "$0")"

長々とした説明

これはどのように機能し、エッジケースやコーナーケースにどのように対処するのでしょうか?

  • 対話型シェルでスクリプトを起動するコマンドを入力します。
  • その対話型シェルは、スクリプトを実行するようbash指示する名前を呼び出します。bash
  • 次に、スクリプトを指す bash 引数を使用してbash呼び出します。dirname
  • 最後に、の出力を引数として をbash呼び出します。cddirname

スクリプト呼び出しコマンド bash口論 dirname口論 cd口論
foo($PATHで見つかりました/path/to/foo) /path/to/foo /path/to/foo /path/to
bash foo foo foo .
/foo /foo /foo /
./foo ./foo ./foo .
"/pa th/to/foo" /pa th/to/foo /pa th/to/foo /pa th/to
"./pa th/to/foo" ./pa th/to/foo ./pa th/to/foo ./pa th/to
"../pa th/to/foo" ../pa th/to/foo ../pa th/to/foo ../pa th/to
"../../pa th/to/foo" ../../pa th/to/foo ../../pa th/to/foo ../../pa th/to
"pa th/to/foo" pa th/to/foo pa th/to/foo pa th/to
--help/foo --help/foo* 該当なし 該当なし
--help 該当なし** 該当なし 該当なし

シンボリックリンクについて

このcdコマンドは、シンボリックリンクが関係している場合は、シンボリックリンクをたどります。シンボリックリンクは通常、たどられるために存在しているため、ほとんどの場合、シンボリックリンクをたどるのが正しい方法です。スクリプトをロードするときに、数マイクロ秒前に同じシンボリックリンクをたどっても問題がなかったのに、スクリプト内のコードがシンボリックリンクをたどると、なぜ問題になるのでしょうか。

ハイフンで始まるコマンド引数の場合

上記の表でハイフンで始まる引数の 2 つのケース (それぞれ * と ** でマークされている) について詳しく説明します。

* の引数がdirnameで始まる可能性があるのは-、相対パスの場合のみです--help/foo。スクリプトが というサブディレクトリにある場合--help、スクリプトの実行は となりbash --help/foo、bash はそのオプションを認識しないため、エラー メッセージが表示されて中止されます。スクリプトは実行されないため、 が何を実行するか--help/fooは問題になりません。cd "$(dirname "$0")"

** スクリプトを呼び出すと、同じディレクトリに--help入力しているときにシェルがコマンドを見つけられなくなることに注意してください--help。または、現在のディレクトリが含まれている場合、スクリプトはまたは$PATHとして実行され、常に文字の前に何かが付きます。/path/to/--help./--help-

bash が で区切られたパラメータを持つコマンドライン引数を導入しない限り、 で区切られたパラメータを含み、bash によって受け入れられる引数を bash に=渡すことは不可能に近いでしょう。-/

dirname引数を受け入れることができる場合--(bash組み込み関数はcd確実に受け入れます--)、スクリプトスニペットを次のように変更できます。

cd -- "$(dirname -- "$0")"

-bash をすり抜けることができる、で始まる議論を構築する方法がわかったら、ぜひコメントしてください。

ご注意

上記のスニペットは bash 以外でも機能します/bin/sh

おすすめ記事