0

スクリプトのソースと実行の唯一の違いは、後者の場合、親環境は影響を受けないことです。

次のサンプル スクリプトを検討してください。

SETUP_DIR=`dirname $0`
echo $SETUP_DIR
echo $0
echo $1

上記のスクリプトは、実行中のスクリプトのディレクトリ名を取得するだけです。ソースを取得しようとすると、上記のスクリプトは次のエラーで失敗します

$ . test.sh foo
dirname: invalid option -- k
Try `dirname --help' for more information.

-ksh
foo

私が思う理由は、それを調達するときに、スクリプトが親環境シェルで実行されるため、シェル名が最初の引数として渡されるため-kshです。

が原因でdirname -ksh失敗します-k。これは無効なオプションですdirname

奇妙なことに、この問題は、sh または bash で実行している場合には発生しません。

$ sh
sh-3.2$ . test.sh foo
.
sh
foo
sh-3.2$ bash
bash-3.2$ . test.sh foo
.
bash
foo
bash-3.2$
  • だから私は疑問に思っていました.KornShell(ksh)で文書化された既知の動作ですか?この問題を解決するにはどうすればよいですか?
  • 私の2番目の一般的な質問は、なぜdirname 'sh'現在のディレクトリを返すのかということです.
4

2 に答える 2

1

In answer to your second question, from man dirname:

Print NAME with its trailing /component removed; if NAME contains no /'s, output '.' (meaning the current directory).

This is why you get . when you run dirname sh.

I am unable to reproduce your error in ksh.

于 2012-12-17T10:11:31.057 に答える
1

だから私は疑問に思っていましたが、それはトウモロコシの殻で文書化された既知の動作ですか? この問題を解決するにはどうすればよいですか?

によって ksh がログイン シェルとして開始されると/bin/login、その$0先頭に が付けられる-ため、単にorではなく に$0なります。Login は、ログイン シェルとして開始されていることをシェルに示すためにこれを行います。これは通常、プロファイルの読み込みに影響するためです。-kshksh/bin/ksh

ksh のマニュアルには、この規則への準拠が記載されています。

シェルが exec(2) によって呼び出され、引数ゼロ ($0) の最初の文字が - である場合、シェルはログイン シェルであると見なされ、コマンドは [...] から読み取られます。

ハイフン プレフィックスは bash では表示されません。bash がコマンド ラインを編集して、プロセス リストに表示されないようにしていると思います。

その結果、dirname $0is dirname -ksh、および dirname は、ksおよびhオプションを渡すものとしてそれを解析しようとします。

dirnamewith--で解析するオプションを明示的に終了することで、これを回避できます。

dirname -- "$0"

私の 2 番目の一般的な質問は、なぜ dirname 'sh' が current directory を返すのかということです。

dirnameあなたが与えているパスのディレクトリ部分がない場合でも、役に立ち、使用可能なパスを返そうとしています。「$0」には 1 つの部分しかないため、現在の作業ディレクトリ、つまりsh==に対して相対的であると想定し./sh.

これは、dogbane's answer に従って文書化されています

于 2012-12-17T10:17:47.037 に答える