2
在Bash-Hackers.org上有關於摺疊功能的nice little wiki entry。基本上,摺疊功能是基於某種條件重新定義自己的功能。基本的例子是類似以下內容:爲什麼管道保持摺疊功能不能保持其新定義?
chatter() {
if [[ $verbose ]]; then
chatter() {
echo "[email protected]"
}
chatter "[email protected]"
else
chatter() {
:
}
fi
}
我認爲這是一個不錯的小把戲,可能是像下面創建功能非常有用:
# 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 "[email protected]"
}
else
#we are running another version. defaulting to BSD
#redefining function
echo osx
my_sed() {
sed -E "[email protected]"
}
fi
my_sed "[email protected]"
}
(回聲聲明只是爲了調試BTW)。這在按照預期運行時以my_sed "s/foo/bar" /tmp/somefile.txt
的形式運行,第一次輸出「gnu」(在Linux上,Mac上是osx),然後保持沉默以供後續運行。但是如果我簡單地使用管道中的函數,函數不會被重新定義,而是會不斷輸出「gnu」。例如:echo 123 | my_sed 's/foo/bar'
每次在shell中運行時都會輸出「gnu」。
這是爲什麼?什麼是管道處理與當前上下文/外殼,使功能保持其新的定義?是否每次管道都分叉一個新進程,以便新的定義從原始shell中丟失?
像我那樣。謝謝! – oligofren
如果您使用的是bash 4.2或更高版本(您必須在Mac OS X上升級,因爲它隨附3.2),您可以在第一次調用my_sed之前使用'shopt -s lastpipe',這將會導致管道中的最後一個命令在當前shell中運行,而不是子shell。這可能會解決問題。 – chepner
好的提示,但不幸的是,即使OS X 10.6(2010年發佈)使用2007年(版本3.2.48)的Bash版本...... – oligofren