我正在尝试从Perl脚本(script.pl)中source
一个脚本。
system ("source /some/generic/script");
请注意,这个通用脚本可以是shell、python或任何其他脚本。而且,我无法将这个通用脚本中的逻辑复制到我的Perl脚本中。我尝试用′、exec
和qx//
替换system
。每次我都得到以下错误:
无法执行“source”:www.example.com第18行没有这样的文件或目录script.pl。
我在网上看到很多论坛,讨论了这个问题的各种原因。但是没有一个提供解决方案。有没有办法从Perl脚本运行/执行source
命令?
3条答案
按热度按时间im9ewurl1#
在bash等中,
source
是一个内置的,意思是 * 读取这个文件,并在本地解释它 *(有点像#include
)。在这种情况下,这样做毫无意义--您要么需要从命令中删除
source
,并在shell脚本的开头添加一个shebang(#!
)行,告诉系统使用哪个shell来执行该脚本,要么需要显式地告诉system
使用哪个shell,例如:[with没有关于在这种情况下使用
system
实际上是否合适的注解]。nkoocmlb2#
这里有几个问题。首先,子进程不能改变其父进程的环境。
source
只会在它的进程存在时存在。下面是一个设置和导出环境变量的简短程序。
运行文件不会导出变量。文件在其自己的进程中运行。进程ID(
$$
)在 set_stuff.sh 和shell中是不同的:source
则不同。它读取文件并在shell中对其进行求值。进程ID在 set_stuff.sh 和shell中是相同的,因此文件实际上影响了它自己的进程:现在来看看Perl,调用
system
会创建一个子进程(其中有一个exec
),因此这不会影响Perl进程。奇怪的是,即使您的版本不能,它也能工作。我认为不同的是,这里没有特殊的shell元字符,所以它试图执行程序目录,跳过它刚才用于我的更复杂的字符串的shell:
但是,在这种情况下,您不希望使用单个字符串。列表形式更安全,但是
source
不是任何东西都可以执行的文件:也就是说,您可以调用
source
,但作为调用shell的对象。回到你的问题上。有很多方法可以解决这个问题,但是我们需要得到程序的输出。不要使用
system
,而要使用反勾号。这是一个双引号上下文,所以我需要保护一些文字$
,我想把它们作为shell命令的一部分传递在反勾号中,您可以得到您想要的内容。shell程序可以看到变量。一旦返回Perl,它就不能了。但是,我现在有了输出。让我们更花哨一些。去掉PID部分,因为我现在不需要看到它:
shell命令会创建一些输出,其名称和值如下:
我可以在Perl中解析输出并设置变量。现在Perl已经导入了shell程序环境的一部分:
让我们看看整个环境。
env
以我刚才处理的方式输出每个值:我在shell中设置了几百个变量,我不想暴露其中的大多数,这些变量都是由Perl进程设置的,所以我可以暂时清除
%ENV
:将其与后处理代码放在一起,您就有了一种将该信息传递回父级的方法。
顺便说一句,这类似于将变量传递回父shell进程的方式,因为输出已经是shell理解的内容,所以使用shell's eval而不是解析它。
z9gpfhce3#
你不能。
source
是一个shell函数,它将脚本的内容“导入”到你当前的环境中。它不是一个可执行文件。您可以通过滚动您自己的功能来复制它的一些功能-运行或解析您正在“获取”的任何内容并捕获结果:
、或类似物。