这是为了简化我遇到的问题。 我定义了一个设置变量的函数,这在这种情况下有效:
$ function myfunc { res="ABC" ; }
$ res="XYZ"
$ myfunc
$ echo $res
ABC
因此调用myfunc改变了res。但是:
$ res="XYZ"
$ myfunc | echo
$ echo $res
XYZ
因此,当myfunc是管道的一部分时,值不会改变。 即使涉及管道,如何使myfunc以我想要的方式工作?
(在真实的剧本中,“myfunc”当然会做一些更精细的事情,管道的另一面有一个zenity进度对话而不是一个无意义的回声)
由于
答案 0 :(得分:4)
这在Unix上是不可能的。要更好地理解这一点,您需要知道变量是什么。 Bash使用所有已定义的变量保留两个内部表。一个是当前shell的本地变量。您可以使用set name=value
或name=value
创建这些广告。这些是当地的过程;创建新进程时,它们不会被继承。
要将变量导出到新的子进程,必须使用export name
将其导出。这告诉bash“我希望孩子们看到这个变量的价值”。这是一个安全功能。
当你在bash中调用一个函数时,它在当前shell的上下文中执行,因此它可以访问和修改所有变量。
但是管道是与I / O管道连接的进程列表。这意味着你的函数在shell中执行,只有{shell}的输出对echo
可见。
即使在myfunc
中导出也无效,因为导出仅适用于您执行导出的shell启动的进程,而echo
由与myfunc
相同的shell启动:< / p>
bash
+-- myfunc
+-- echo
echo
不是myfunc
的孩子。
解决方法:
答案 1 :(得分:4)
正如@Aaron所说,问题是由子shell中运行的函数引起的。但是有一种方法可以在bash中避免这种情况,使用进程替换而不是管道:
myfunc > >(echo)
这与管道的作用大致相同,但myfunc在主shell而不是子进程中运行。请注意,这是一个仅限bash的功能,并且必须使用#!/ bin / bash作为你的shebang才能工作。