web-dev-qa-db-ja.com

/ bin / shが/ bin / bashとは異なる振る舞いをするのはなぜですか?

シェルで この質問 の答えを調べている間、/bin/shがシステム上の/bin/bashを指していても、2つのコマンドの動作が異なることに気付きました。 。まず、の出力

ls -lh /bin/sh

は:

lrwxrwxrwx 1 root root 4 Apr 22  2013 /bin/sh -> bash*

ただし、/bin/shを介して次のコマンドを呼び出します。

/bin/sh -c "script.sh 2> >( grep -v FILTER 2>&1 )"

このエラーを返します:

/bin/sh: -c: line 0: syntax error near unexpected token '>'
/bin/sh: -c: line 0: 'script.sh 2> >( grep -v FILTER 2>&1 )'

/bin/bashを介して同じコマンドを実行しているとき:

/bin/bash -c "script.sh 2> >( grep -v FILTER 2>&1 )"

正常に実行されます。出力は次のとおりです。

This should be on stderr

参考のため、script.shの内容は次のとおりです。

#!/bin/sh
echo "FILTER: This should be filtered out" 1>&2
echo "This should be on stderr" 1>&2
echo "FILTER: This should be filtered out" 1>&2

2つの呼び出しの動作が異なるのはなぜですか?

64
Squirrel

bash$argv[0](bashはCで実装されています)の値を見て、どのように呼び出されたかを判断します。

shとして呼び出されたときの動作は文書化されています マニュアル内

Bashがshという名前で呼び出された場合、POSIX標準にも準拠しながら、shの履歴バージョンの起動時の動作を可能な限り模倣しようとします。

対話型ログインシェルとして、または-loginオプションを使用した非対話型シェルとして呼び出されると、最初に/etc/profileおよび~/.profileからこの順序でコマンドを読み取って実行しようとします。 --noprofileオプションを使用して、この動作を禁止できます。 shという名前の対話型シェルとして呼び出された場合、Bashは変数ENVを探し、値が定義されている場合はその値を展開し、展開した値をファイルの名前として使用して読み取り、実行します。 shとして呼び出されたシェルは、他のスタートアップファイルからコマンドを読み取って実行しようとしないため、--rcfileオプションは効果がありません。 shという名前で呼び出された非対話型シェルは、他のスタートアップファイルを読み取ろうとしません。

shとして呼び出された場合、Bashは起動ファイルが読み取られた後にPOSIXモードに入ります

bashがPOSIXモードの場合に変更されるものの長いリスト(現在46項目)があります ここに記載

(おそらくPOSIXモードは、_bash以外のシェルへの移植性についてスクリプトをテストする方法として主に有用です。)

ちなみに、呼び出された名前に応じて動作を変更するプログラムはかなり一般的です。 grepfgrep、およびegrepの一部のバージョンは、単一の実行可能ファイルとして実装されます(ただし、GNU grepは ' viewは通常viまたはvimへのシンボリックリンクであり、viewとして呼び出すと読み取り専用モードで開きます。 Busybox systemには、マスターbusybox実行可能ファイルへのすべてのシンボリックリンクである多数の個別のコマンドが含まれています。

79
Keith Thompson

Bashをshとして呼び出すと、通常読み込まれるスタートアップファイルを読み込んだ後にposix modeになります(POSIX shが読み込むスタートアップファイルとは異なります)。モード。これらのモードについては、マニュアルのINVOCATIONセクションから確認できます。 POSIXモードについて詳しく説明します。

POSIXモード

このモードは、bashがさまざまな程度でPOSIXの期待に準拠しようとすることを意味します。 here で説明したように、bashには、このモードに対していくつかの異なる呼び出しがあり、わずかに異なる影響があります。

  1. sh:起動ファイルを読み取った後、BashはPOSIXモードに入ります。
  2. bash --posix:BashはPOSIXモードに入りますbeforeスタートアップファイルの読み取り。
  3. set -o posix:BashはPOSIXモードに切り替わります。
  4. POSIXLY_CORRECT:bashの起動時にこの変数が環境内にある場合、シェルはposixモードに入りますbeforebash --posixなどの起動ファイルを読み取ります。 set -o posixのように、bashの実行中に設定されている場合。
20
kojiro

Bash Reference Manual から:

Bashがshという名前で呼び出された場合、POSIX標準にも準拠しながら、shの履歴バージョンの起動時の動作を可能な限り模倣しようとします。

16
Etan Reisner

bashバイナリは、それがどのように呼び出されたかを確認するため(argv[0]shとして実行されている場合、互換モードに入ります。

10
Carl Norum