为什么管道保持折叠功能不保持其新定义?

oli*_*ren 2 unix bash scripting

在Bash-Hackers.org上有一个关于折叠功能的不错的小wiki条目.基本上,折叠函数是根据某些条件重新定义自身的函数.基本示例如下:

chatter() {
  if [[ $verbose ]]; then
    chatter() {
      echo "$@"
    }
    chatter "$@"
  else
    chatter() {
      :
    }
  fi
}
Run Code Online (Sandbox Code Playgroud)

我认为这是一个很好的小技巧,可能对创建如下函数很有用:

# a portable extended regular expression sed for Linux and Mac
# simply checks if using an option fails for one version
# @see http://wiki.bash-hackers.org/howto/collapsing_functions
my_sed() {
    if ( echo abc | sed -r /abd/p > /dev/null 2>/dev/null ) ; then 
        #we are running a GNU version. redefine function
        echo gnu
        my_sed() {
            sed -r "$@"
        }
    else 
        #we are running another version. defaulting to BSD
        #redefining function
        echo osx
        my_sed() {
            sed -E "$@"
        }
    fi
    my_sed "$@"
}
Run Code Online (Sandbox Code Playgroud)

(echo语句仅用于调试btw).这在运行时按预期工作my_sed "s/foo/bar" /tmp/somefile.txt,第一次输出"gnu"(在Linux上,在Mac上是osx),然后在后续运行中保持静默.但是如果我只是在管道中使用该函数,则不会重新定义该函数,不断输出"gnu".示例:echo 123 | my_sed 's/foo/bar'每次在shell中运行时都会输出"gnu".

为什么是这样?什么是管道使用当前上下文/ shell来保持函数不保持其新定义?管道是否每次都要分配一个新进程,以便新的定义从原始shell中丢失?

Wil*_*ell 5

管道在子shell中运行,并且子shell退出时重新定义将丢失.