web-dev-qa-db-ja.com

現在のスクリプトと同じディレクトリでスクリプトを実行します

同じフォルダーに2つのBashスクリプトがあります(リポジトリー全体をダウンロードするユーザーによってどこかに保存されます):

  • _script.sh_はユーザーによって実行されます
  • _helper.sh_は必須で、_script.sh_によって実行されます

2つのスクリプトは同じディレクトリにある必要があります。 2番目のスクリプトを呼び出すには最初のスクリプトが必要ですが、2つの問題があります。

  1. ユーザーが最初のスクリプトをどのように実行しているかわからないため、現在の作業ディレクトリを知ることは役に立たない(_/usr/bin/script.sh_、_./script.sh_、または_../Downloads/repo/scr/script.sh_)
  2. スクリプト_script.sh_は、_helper.sh_を呼び出す前に別のディレクトリに変更されます。

現在のディレクトリ を変数に格納することでこれを行うBashを完全にハックすることはできますが、そのコードは非常に一般的で単純なタスクであるため、不必要に複雑に思えます。

_helper.sh_内から_script.sh_を確実に呼び出す標準的な方法はありますか?また、Bashがサポートされているどのオペレーティングシステムでも動作しますか?

35
IQAndreas

_$0_は実行中のスクリプトの完全なパスを保持しているため、スクリプトに対して dirname を使用してスクリプトのパスを取得できます。

_#!/bin/bash

script_name=$0
script_full_path=$(dirname "$0")

echo "script_name: $script_name"
echo "full path: $script_full_path"
_

たとえば、_/tmp/a.sh_に保存すると、次のような出力が表示されます。

_$ /tmp/a.sh
script_name: /tmp/a.sh
full path: /tmp
_

そう

  1. ユーザーが最初のスクリプトをどのように実行しているかわからないため、現在の作業ディレクトリを知ることは役に立たない(_/usr/bin/script.sh_、_./script.sh_、または_../Downloads/repo/scr/script.sh_)

_dirname "$0"_を使用すると、元のパスを追跡できます。

  1. スクリプト_script.sh_は、_helper.sh_を呼び出す前に別のディレクトリに変更されます。

繰り返しますが、_$0_にパスがあるので、cdに戻ることができます。

44
fedorqui

多くの開発者は、$ 0は nsafe と見なされます。別の解決策を見つけました。bashスクリプトのチェーンとsourceに対して安全です。

A.shが(同じフォルダーにある)b.shをchildbashプロセスを使用して実行する必要がある場合:

#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
bash ${__dir}/b.sh

A.shがsamebashプロセスを使用してb.sh(同じフォルダーにある)を実行する必要がある場合:

#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source ${__dir}/b.sh
6
Eugen