このソフトリンクが期待どおりに機能しないのはなぜですか?


11
bash4.3 # pwd
/bin
bash4.3 # ll sh
lrwxrwxrwx. 1   root    root    4   May 17 22:22 sh -> bash
bash4.3 # ll bash
-rwxr-xr-x. 1   root    root    1072056 May 17 22:22 bash
bash4.3 # bash
bash4.3 # sh
sh-4.3#

私のOSはfedora 24(デフォルトのGNOMEバージョン)です。

例から、我々は知ることができます:下/binbashバイナリ実行ファイルです。shへのソフトリンクbashです。

したがって、私の知る限り、type bash and press enterと同じ結果を正確にもたらす必要がありますtype sh and press enter

とき私はtype bash and press enter、私が得る[root@localhost bin]#予想通り。

しかし、もし私ならtype sh and press enter、私は驚くほど得るsh-4.3#

原因は何ですか?


SEエディターにイメージとして非常に簡単にコピーアンドペーストできるテキストは非常に迷惑なので、これを行わないでください。代わりに、ターミナルでテキストを選択し、CTRL-SHIFT-Cを押します。

回答:


25

これは文書化された機能です。

という名前のシンボリックリンクを介してbashを実行するとsh、bashはsh互換モードで起動します。

からman bash

shという名前でbashが呼び出されると、POSIX標準にも準拠しながら、shの歴史的なバージョンの起動時の動作を可能な限り模倣しようとします。対話型ログインシェル、または--loginオプションを使用した非対話型シェルとして呼び出されると、最初に/ etc / profileと〜/ .profileの順にコマンドを読み取って実行しようとします。--noprofileオプションを使用して、この動作を禁止できます。shという名前の対話型シェルとして呼び出されると、bashは変数ENVを探し、定義されている場合はその値を展開し、展開された値を読み取りおよび実行するファイルの名前として使用します。shとして起動されたシェルは、他の起動ファイルからコマンドを読み取って実行しようとしないため、-rcfileオプションは効果がありません。shという名前で呼び出された非対話型シェルは、他の起動ファイルを読み取ろうとしません。shとして呼び出されると、bashは起動ファイルが読み取られた後にposixモードに入ります。

プログラムは、起動に使用された名前をどのように知るのですか?

ACプログラムの場合、検査できargv[0]ます。シェルまたはperlスクリプトの場合、検査でき$0ます。

例として、この単純なシェルスクリプトを考えてみましょう。

$ cat utc
#!/bin/sh
case "${0##*/}" in
        utc) date -u ;;
        et) TZ=US/Eastern date ;;
esac

$0スクリプトの呼び出し元の名前です。 ${0##*/}ディレクトリ名が削除された状態でスクリプトが呼び出された名前です。

このシンボリックリンクを作成しましょう:

ln -s utc et

そのためutcet両方とも同じ実行可能ファイルを実行しますが、結果は異なります。として実行するとutc、世界時が出力されます。として実行するとet、米国東部時間を出力します。例えば:

$ utc
Wed Jul 20 18:14:18 UTC 2016
$ et
Wed Jul 20 14:14:20 EDT 2016

4
OPは呼び出しが同一であることを期待しているため、これが可能な方法を追加したい場合があります。(argv[0]、obvs)
軌道上の明るさのレース

@LightnessRacesinOrbitいいね。例を追加しました。
John1024

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.