5

次の内容のスクリプト「task.sh」があります。

#!/bin/bash

CUR_DIR=`pwd`
SCRIPTPATH="${CUR_DIR}/`dirname $0`"

「bashtask.sh」で呼び出すと期待どおりに動作しますが、「。task.sh」で呼び出すと

$ . log/task.sh 
dirname: invalid option -- b
Try `dirname --help' for more information.

スクリプトがcrontabでスケジュールされている場合、スクリプトも機能しません。現在のディレクトリではないスクリプトのディレクトリを取得するために、私が間違っていることや別の方法を教えてもらえますか?

4

4 に答える 4

7

として呼び出すとbash task.sh、bash は「task.sh」を $0 に割り当てます ( bash のマニュアルから:「Bash がコマンドのファイルで呼び出された場合 [...] $0 はそのファイルの名前に設定されます。」)。

ファイルをソースすると、bash は $0 を変更せず、現在の環境でスクリプトを実行するだけです。現在の環境で $0 に含まれるものは何ですか?

$ echo "$0"
-bash

先頭のダッシュは、 によってdirnameオプションとして解釈されます。

それがcronジョブにある場合、なぜそれを調達しているのですか?

スクリプトをソースする必要がある場合、シェルが bash の場合、これは機能します。

SCRIPTPATH="${CUR_DIR}/${BASH_ARGV[0]}"

ただし、cron のシェルは /bin/sh だと思います。/bin/sh が bash へのシンボリック リンクであっても、bash が sh として呼び出されると、POSIX として動作しようとします: BASH_ARGV 配列はおそらく利用できません。

于 2011-04-18T20:28:55.947 に答える
1

bash を使用する場合、pwdやなどの外部バイナリを呼び出す理由はありません。dirnameこれら 2 つのバイナリの機能は、純粋なシェル構文で複製できます。

次のことを試してください。

#!/bin/bash

CUR_DIR="$PWD"
SCRIPTPATH="${CUR_DIR}/${0#*/}"
于 2011-04-18T20:21:17.660 に答える
1

入力すると、

bash foo.sh

スクリプト foo.sh を実行していて、bash は入力引数 $0 を実行中のスクリプトの名前に設定します。

入力すると、

. foo.sh

スクリプトを取得していて、入力引数 $0 が設定されていません。この状況では、最後に実行されたコマンドの引数を含む自動変数 $_ を使用できます。スクリプトでは、次のように入力できます。

SCRIPTPATH=$(dirname "$_")

foo.sh のパスを取得します。これが機能するには、これがファイル内で実行される最初のコマンドでなければならないことに注意してください。それ以外の場合、 $_ にはソース スクリプトのパスが含まれません。

同様の質問に対してこの回答を提供してくれたDennis Williamsonに感謝します。

于 2014-03-05T09:21:15.047 に答える