【发布时间】:2014-01-08 21:15:13
【问题描述】:
关于函数、变量范围和可能的子shell,我对我的脚本有点困惑。 我在另一个post 中看到管道生成一个子shell,而父shell 无法从子shell 访问变量。在反引号中运行的 cmd 是否也是这种情况?
为了不让人感到厌烦,我缩短了 100 多行脚本,但我尽量记住保留重要元素(即反引号、管道等)。希望我没有遗漏任何内容。
global1=0
global2=0
start_read=true
function testfunc {
global1=9999
global2=1111
echo "in testfunc"
echo $global1
echo $global2
}
file1=whocares
file2=whocares2
for line in `cat $file1`
do
for i in `grep -P "\w+ stream" $file2 | grep "$line"` # possible but unlikely problem spot
do
end=$(echo $i | cut -d ' ' -f 1-4 | cut -d ',' -f 1) # possible but unlikely spot
duration=`testfunc $end` # more likely problem spot
done
done
echo "global1 = $global1"
echo "global2 = $global2"
所以当我运行我的脚本时,最后一行显示 global1 = 0。但是,在我的函数 testfunc 中,global1 设置为 9999,调试消息至少在函数内打印出它是 9999。
这里有两个问题:
- 反引号是否生成子shell,从而使我的脚本不 工作?
- 如何解决此问题?
【问题讨论】:
-
1.是的,他们这样做 2. 快速修复:删除反引号并在函数定义中移动分配。或者写 global1= `testfunc $end `
-
顺便说一句,那些嵌套的
for循环看起来非常扭曲且效率低下。我猜你想说grep -P "\w+ stream" "$file2" | grep -f "$file1" | while read i; do... -
@damienfrancois,谢谢您的回复。 testfunc 修改了几个全局变量。我想这是我忘记包括在内的一件事。
-
好的,那么您可以尝试用简单的
testfunc $end替换duration= ` testfunc $end `并在函数体中添加duration=...。您真的可以将 bash 函数视为简单地内联扩展的宏。