我试图解决一个问题,在我看来,你无法将开放的db2连接传递给子shell。
我的代码组织如下:
驱动程序脚本(在my_driver.sh
)
# foo.sh defines baz() bar(), which use a db2 connection
# Also the "$param_file" is set in foo.sh!
source foo.sh
db2 "connect to $dbName USER $dbUser using $dbPass"
function doit
{
cat $param_file | while read params
do
baz $params
bar $params
done
}
doit
我已经简化了我的代码,但上面的内容已经足够了。我从上面开始:
my_driver.sh
现在,我真正的问题是子shell中没有db2连接:
我累了:
. my_driver.sh
没有帮助
如果我从命令行手动执行此操作:
source foo.sh
我手动设置$params
:
baz $params
bar $params
然后它确实有效!因此,似乎doit
或其他内容的行为就像从子shell执行bar
和baz
一样。
如果我能以某种方式弄清楚如何将db2 open connection传递给subshell,那我会很高兴。
否则,这些shell函数在我看来是在子shell中运行的。有办法吗?
答案 0 :(得分:6)
shell不会创建子shell来运行函数。
当然,它确实为许多其他目的创造了子壳,并非所有这些都可能是显而易见的。例如,它在|
的实现中创建子shell。
db2
要求所有db2
命令与建立连接的db2
命令具有相同的父命令。您可以使用以下内容记录PID:
echo "Execute db2 from PID $$" >> /dev/stderr
db2 ...
(只要db2命令不在管道或shell括号内执行。)
显示的代码中的一个可能的问题(具有完全不同的症状)是使用非标准语法
function f
定义一个功能。期望标准shell
f()
Bash理解这两者,但是如果你没有使用shebang行或使用sh
命令执行脚本文件,你将最终使用系统的默认shell,这可能不是是bash。
答案 1 :(得分:0)
找到解决方案,但无法完全解释问题....
如果你按照以下方式更改function doit
{
while read params
do
baz $params
bar $params
done < $param_file
}
就行了!
echo debug check with PID=$$ PPID=$PPID and SHLVL=$SHLVL
只是,我不确定为什么?以及我如何证明它......
如果我坚持使用调试代码:
|
我与cat $param_file | while read params
取得了相同的结果。我知道while (false != $row = mysqli_fetch_assoc($query2))
echo $row["total_likes"];
创建了一个子shell,但是,我的调试语句总是显示相同的PID和PPID ......
所以我的问题解决了,但我错过了一些解释。
我也想知道这个问题是不是更适合unix.stackexchange社区?