我正在对系统进行一些调用,主要是cd
命令,因为某些函数需要从系统上的某些目录中调用。然而,我注意到,一旦通话结束,该通话的效果就会丢失。
例如,假设我从/home/project
开始,然后调用:
system("setenv home/project/env/NeededEnvironment");
system("make cfile.o");
第二个系统调用不知道第一个调用设置文件编译所需的环境。我也尝试过将它们放入一个由;
分隔的系统调用中,但遇到了同样的问题。是否存在要保存的第一个调用的效果?
system
就是这样工作的:它创建了一个子shell来执行命令,当命令完成时,子shell退出,使perl
进程不受影响。
Perl常见问题解答的第8节也回答了这个问题。
我在一个perl脚本中{更改了目录,修改了环境}。为什么我退出脚本时更改就消失了?如何使更改可见
- Unix
从最严格的意义上讲,这是不可能完成的——脚本的执行过程与它启动时的shell不同。对进程的更改不会反映在其父进程中,只反映在更改后创建的任何子进程中。有一种shell魔术,可以让你通过在shell中
eval()
处理脚本的输出来伪造它;有关详细信息,请查看comp.unix.questions常见问题解答。
你想要的代码
system("cd /home/project/env/NeededEnvironment && make cfile.o") == 0
or warn "$0: make failed";
或者对make
使用-C
选项,避免像中那样解析shell参数
system("make", "-C", "/home/project/env/NeededEnvironment", "cfile.o") == 0
or warn "$0: make failed";
如果您正在编写Perl脚本,请尽可能少地使用Perl本身和shell。
如果您需要更改目录:
chdir 'some/other/dir';
如果需要设置环境变量:
$ENV{ SOME_VAR } = 'Some value';
更新
以下是一些不应该使用shell等价物的命令:
mkdir
unlink
rmdir
每个人都应该知道的模块:
File::Copy
File::Path
File::Basename
File::Spec