Bashスクリプトからフルパスを取得する

Bashスクリプトからフルパスを取得する

相対パスを使用するbashスクリプトがあります。スクリプトが保存されているディレクトリと同じ作業ディレクトリが必要です。プロンプトで実行すると、まずスクリプトディレクトリにCDを移動できるため、うまく機能します。ただし、/etc/cron.hourly でスクリプトへのシンボリックリンクを生成すると、スクリプトは中断されます。

bashスクリプトディレクトリをスクリプトが格納されているディレクトリに変更する方法が必要です。しかし、私はこれまで成功していませんでした。スクリプトがシンボリックリンクを介してcronから呼び出されても、これを行う簡単な方法はありますか?

答え1

通常、シェルはスクリプトを読む必要があるため、常にスクリプトパスを知っています。場合によってはそうではありません。setuidスクリプトこれをサポートするオペレーティングシステム(Linuxではない)では - しかし、setuidシェルスクリプトはとにかく悪い考えです。さらに、スクリプトは、シェルが開いた時間とそれを使用して作業しようとした時間の間に移動した可能性があります。したがって、セキュリティや信頼性の問題がない場合にのみスクリプトパスを使用してください。構造が既知のパッケージは有効なユースケースです。

シェルインタプリタに渡されたスクリプトパスは特別なパラメータにあります$0。相対パスである可能性があるため、使用するには別のディレクトリに変更する前に使用してください。この間にスクリプトが移動されないことがわかっている場合は、それを使用できます。

シンボリックリンクである可能性があるため、ターゲットをインポートする$0必要があります。これを行うPOSIXメソッドはありませんが、Linux(GNU coreutilsまたはBusyBox)と最近はBSDでreadlink -f利用できます。標準絶対パス

script_path_in_package=$(readlink -f -- "$0")
script_directory=${script_path_in_package%/*}

これにより、パッケージの構築方法が制限されます。たとえば、アーキテクチャに依存しないディレクトリツリーにスクリプトを配置し、各アーキテクチャ固有のディレクトリツリー内でそのスクリプトに接続することはできません。

答え2

正確に属性を指定できるように、この情報をどこで取得したのか覚えていませんが、実行中のスクリプトへの「標準」パスを取得するために長い間この情報を使用してきました。仕様によると、「.」のない絶対パスを意味します。または「..」が含まれています。

CANON=$(cd -P -- "$(dirname -- "$0")" && printf '%s\n' "$(pwd -P)/$(basename -- "$0")")

必要に応じて、$ CANONのデフォルト名とディレクトリ名を使用してこれらの値を取得します。

答え3

あなたはこれを行うことができるはずです。

  • $ 0パラメーターは、スクリプトを呼び出すとフルパス(名前を含む)に拡張されます。
  • 組み込みシェル機能テスト(または[ ])以下を使用して、パスがシンボリックリンクであるかどうかをテストできます。-エル
  • ls -l、シンボリックリンクに適用すると、実際のパスが最終フィールドとして含まれる単一の出力ラインが提供されます。

これはソースの位置を発見するのに十分です。もちろん、これは再帰的にこれを行う必要があるシンボリックリンクです。

答え4

この変数は$0プログラムの名前を保持します。する

cd $(dirname $( readlink $0) )

プログラムがあるディレクトリに移動します。

はい、$0 問題がある可能性があります。、一般的な場合に使用される場合。設定が明確に定義された特定の状況では、本人の業務に活用しても大丈夫そうです。

特に、スクリプトはとにかく作業のためにそのディレクトリを使用しないでください。環境変数や設定ファイルに依存する必要があります。それでは、「スクリプトを起動してから誰かがスクリプトを移動した可能性があります」またはkshがこれを詳しく説明する方法に興味があるのはなぜですか? (これがbashスクリプトであることを知っていると仮定します)。

関連情報