Skip to main content
modern bash can have ksh-like pipe behavior (thanks s3c)
Source Link
Gilles 'SO- stop being evil'
  • 865.3k
  • 205
  • 1.8k
  • 2.3k

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2. You can get this behavior in modern bash by setting the lastpipe option with shopt -s lastpipe (in an interactive shell, you also need to disable job control with set +m).

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2. You can get this behavior in modern bash by setting the lastpipe option with shopt -s lastpipe (in an interactive shell, you also need to disable job control with set +m).

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link

The right explanation has already been given by jsbillingsjsbillings and geekosaurgeekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}
added 5 characters in body
Source Link
Gilles 'SO- stop being evil'
  • 865.3k
  • 205
  • 1.8k
  • 2.3k

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zshzsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | {
  while read var ; do x=55 ; done
  echo x=$x 
}
added 2 characters in body
Source Link
GAD3R
  • 69.9k
  • 32
  • 147
  • 216
Loading
Source Link
Gilles 'SO- stop being evil'
  • 865.3k
  • 205
  • 1.8k
  • 2.3k
Loading