現在の関数がコマンド置換で呼び出されたことを確認できますか?

現在の関数がコマンド置換で呼び出されたことを確認できますか?
foo() {
  if [[ something ]]; then
    echo "The foo function was called directly."
  else
    echo "The foo function was invoked via command substitution."
  fi
}

fooに直接電話してください:

foo

foo 関数が直接呼び出されます。

コマンド置換を介してfooを呼び出します。

a=$(foo) || exit 1
echo "${a}"

foo 関数はコマンド置換によって呼び出されます。

これを行う方法はありますか?

答え1

私はあなたが使用できる1つのテストが次のようになると思います。

if [[ $BASHPID -eq $$ ]]; then
    echo was called directly
else
    echo was called in a subshell
fi

特殊値$$は、スクリプトを実行するシェルのプロセスIDです。これはサブシェルでは変更されません(コマンドの置き換えもその1つです)。

特殊値は、$BASHPID現在のコードを実行しているシェルのプロセスIDになります。この値会議サブシェル内で変更します。

したがって、異なる場合、サブシェルから関数が呼び出されます。私が知っている限り、このサブシェルがコマンドの代替であるかどうか、それが他のサブシェルであるかどうかを知る方法はありません。

また、使用することができます

if [[ $BASH_SUBSHELL -eq 0 ]]; then
    echo was called directly
else
    echo was called in a subshell
fi

表示されたコードと同じ効果を得るために。

この変数は、ネストされたサブシェルの各追加レベルに対して0から増加しますBASH_SUBSHELL

関連情報