如何在脚本中区分“命令替换”和“子shell”?

时间:2014-03-04 04:41:01

标签: bash subshell command-substitution

我需要区分两种情况:( …subshell… ) vs $( …command substitution… )

我已经拥有以下函数,该函数区分在命令替换或子shell中运行并直接在脚本中运行。

#!/bin/bash
set -e

function setMyPid() {
    myPid="$(bash -c 'echo $PPID')"
}

function echoScriptRunWay() {
    local myPid
    setMyPid
    if [[ $myPid == $$ ]]; then
        echo "function run directly in the script"
    else
        echo "function run from subshell or substitution"
    fi
}

echoScriptRunWay
echo "$(echoScriptRunWay)"
( echoScriptRunWay; )

示例输出:

function run directly in the script
function run from subshell or substitution
function run from subshell or substitution

期望的输出

但我想更新代码,以便区分命令替换和子shell。我希望它产生输出:

function run directly in the script
function run from substitution
function run from subshell

P.S。我需要区分这些情况,因为在命令替换和子shell中运行时,Bash对内置trap命令有不同的行为。

P.P.S。我也关心echoScriptRunWay | cat命令。但这对我来说是个新问题,我创建了here

1 个答案:

答案 0 :(得分:0)

我不认为可以可靠地测试命令是否在命令替换中运行。

您可以测试stdout是否与主脚本的stdout不同,如果是,则大胆推断它可能已被重定向。例如

samefd() {
    # Test if the passed file descriptors share the same inode
    perl -MPOSIX -e "exit 1 unless (fstat($1))[1] == (fstat($2))[1]"
}

exec {mainstdout}>&1

whereami() {
    if ((BASHPID == $$))
    then
        echo "In parent shell."
    elif samefd 1 $mainstdout
    then
        echo "In subshell."
    else
        echo "In command substitution (I guess so)."
    fi
}

whereami
(whereami)
echo $(whereami)