从 Ubuntu 14.04 迁移到 16.04 时,我注意到我的几个 Bash 脚本由于缺少导出函数而失败。我想知道这是否与修复有关炮弹休克虫,尽管我只是简单地export -f
函数,而不依赖于 Bash 内部函数表示。仅当中间有另一个进程时,故障才不会发生在直接 Bash 子 shell 中。例如,Bash 调用 awk / Perl / Vim 调用另一个 Bash。下面是一个 Perl 的例子:
Good
$ foo() { echo "foobar"; }
$ export -f foo
$ export -f; foo
foo ()
{
echo "foobar"
}
declare -fx foo
foobar
$ bash -c "export -f; foo"
foo ()
{
echo "foobar"
}
declare -fx foo
foobar
$ perl -e 'system("bash -c \"export -f; foo\"")'
foo ()
{
echo "foobar"
}
declare -fx foo
foobar
$ echo $BASH_VERSION
4.3.11(1)-release
Bad
$ foo() { echo "foobar"; }
$ export -f foo
$ export -f; foo
foo ()
{
echo "foobar"
}
declare -fx foo
foobar
$ bash -c "export -f; foo"
foo ()
{
echo "foobar"
}
declare -fx foo
foobar
$ perl -e 'system("bash -c \"export -f; foo\"")'
bash: foo: command not found
$ echo $BASH_VERSION
4.3.42(1)-release
我做错了什么,还是这是一个错误?
Edit:@chepner 指出 Bash 使用专门命名的 shell 标识符来存储函数。当经过dash
(0.5.8-2.1ubuntu2,与 0.5.7-4ubuntu1 一起使用),这些标识符将被删除。和ksh
,他们还活着。我检查过
$ dash
$ sudo strings /proc/$$/environ | grep foo # Still passed from Bash to Dash
BASH_FUNC_foo%%=() { echo "foobar"
$ bash
$ sudo strings /proc/$$/environ | grep foo # But went missing from Dash to Bash
$ exit
$ exit
$ ksh
$ sudo strings /proc/$$/environ | grep foo
BASH_FUNC_foo%%=() { echo "foobar"
$ bash
$ sudo strings /proc/$$/environ | grep foo # Kept from Ksh to Bash
BASH_FUNC_foo%%=() { echo "foobar"
同样,Vim 的行为可以通过以下方式改变:set shell=/bin/bash
/ :set shell=/bin/ksh
So, is dash
惹的祸?!
长话短说:已知dash
问题;灰色区域,可能是固定的;最好不要依赖在非 bash 父级中幸存的导出。
这是由 dash 0.5.8 的变化引起的; cp。dash 从环境中删除导出的 bash 函数.
对于这个问题是否会得到解决,目前尚未达成共识。 POSIX 似乎允许剥离无效的环境条目,其他(更晦涩的)shell 显然也这样做,但它会在各种应用程序中引起问题,特别是因为/bin/sh
符号链接到dash
(因此也是 Ubuntu 中的默认 shell)。
我的个人用例是我放入我的一些简短的实用函数~/.profile
,我在一些 shell 脚本中引用了它。其中之一以自动启动的方式运行Conky守护进程,并且该守护进程错过了这些功能,因为自动启动是通过dash
。我可以解决这个问题。这FPATH
Korn shell 的自动加载机制在 Bash 中也很不错......
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)