スクリプトが呼び出されるディレクトリに変更する最も安全な(または最もエレガントな、または最も短い)方法は何ですか?

スクリプトが呼び出されるディレクトリに変更する最も安全な(または最もエレガントな、または最も短い)方法は何ですか?

スクリプトが呼び出されるディレクトリに変更する安全な、またはUnix互換の方法が何であるかを知りたいです。

どちらの方法も、引用符なしでスペースと特殊文字を含むディレクトリでも機能します。しかし、場合によってはこれがうまくいかないかもしれません。それともありますか?

#!/bin/bash

cd $(dirname $0)
pwd
cd ${0%/*}
pwd

~/test 1"\ ü`\($$ ./cd.sh
/home/syss/test 1"\ ü`\($
/home/syss/test 1"\ ü`\($

答え1

これは$0相対パスである可能性があるため、cd2回呼び出すと機能しない可能性があります。また、$0プロジェクトのディレクトリ部分を抽出します。最大ケース。最大等しくないみんな。失敗する可能性のある状況は次のとおりです。

  • スクリプトはそのパスを実行して呼び出されるのではなく、そのパスからシェルを呼び出すことによって呼び出されますbash myscript(例:find )。PATH
  • 実行中にスクリプトが移動します。

スクリプトを無駄に呼び出す必要があることを文書化した場合は、ディレクトリセクションを使用できます$0

$0空の項目で見つかった場合PATHや一部のシェルの場合は注意が必要ですPATH.この場合は支援を受ける価値があるため、予防措置を講じる必要があります${0%/*}

このdirnameアプローチも完全に単純ではない。コマンド置換は最後に改行文字を食べます。 2つの方法のいずれかを使用する場合は、文字列が-オプションで始まり解釈される可能性があることに注意してください。パスは--コマンドのオプションのリストを終了します。

case "$0" in
  */*) cd -- "${0%/*}";;
  *) cd -- "$0";;
esac

または

cd -- "$(dirname -- "$0"; echo /)"

二重引用符について間違った質問をしました。"$0"パラメータの値です0$00引用符なしでは、各要素の文字から分割されたパラメータ値ですIFS。これはワイルドカードパターンとして解釈され、一致するファイル(存在する場合)に置き換えられます(後者はワイルドカードがオフになっていない場合のみ)。。パラメータの値が0各要素の文字で分割され、次にワイルドカードパターンとして解釈され、一致するファイルがある場合は置き換えられますIFS(後者はワイルドカードがオフになっていない場合にのみ)。パラメータの値を意味します0。だから何を意味するのか書き留めてください"$0"

テストがブロックされない唯一の理由は、問題の名前を使用しようとせず、この特定のシナリオでエラーを修正する特定のシェルを使用してテストしているためです。このようなディレクトリ名を使用すると、foo barコマンドに2つの引数を渡し、foobashのコマンドはそれを「接続、空白、および取得したディレクトリに変更」と解釈し、正しい名前が再構成されます。他のシェルでは、これを「偽の引数に対する苦情」、「ディレクトリに変更」、または「現在の作業ディレクトリからに置き換えて得られたディレクトリに変更」と解釈できます。たとえば、bashを使用すると、名前に2つの連続した空白が含まれていると、スクリプトは失敗します。barcdcdfoobarfoofoobar

関連情報