bashsubshell

Why BASH_SUBSHELL is always 0 no matter `lastpipe` is enabled or not?


I have done some research on pipe and subshell

Each command in a multi-command pipeline, where pipes are created, is executed in its own subshell, which is a separate process (see Command Execution Environment). If the lastpipe option is enabled using the shopt builtin (see The Shopt Builtin), the last element of a pipeline may be run by the shell process when job control is not active.

test code

#!/bin/bash


set +m

shopt -u lastpipe
shopt | grep lastpipe

function test() {
  echo "This is first pipe"  | echo $BASH_SUBSHELL
}

test

shopt -s lastpipe
shopt | grep lastpipe

function test() {
  echo "This is first pipe"  | echo $BASH_SUBSHELL
}

test

Output is

lastpipe        off
0
lastpipe        on
0

Expected result is

lastpipe        off
1
lastpipe        on
0

Solution

  • Your problem is that variable substitution is performed before the pipeline runs. When you write:

    echo "This is first pipe"  | echo $BASH_SUBSHELL
    

    The $BASH_SUBSHELL is expanded in the current shell before it runs the pipeline. To properly perform your test, you would need to place your echo statement in a function to defer substitution:

    test_subshell() {
      echo $BASH_SUBSHELL
    }
    

    Then you will see different behavior:

    $ test_subshell
    0
    $ echo "This is first pipe" | test_subshell
    1