3

我正在对系统进行一些调用,主要是cd命令,因为某些函数需要从我系统上的某些目录中调用。但是,我注意到一旦通话结束,该通话的效果就会丢失。

例如,假设我开始/home/project然后调用:

 system("setenv home/project/env/NeededEnvironment");
 system("make cfile.o");

第二个系统调用不知道第一个调用设置文件编译所需的环境。我也尝试将它们放入一个系统调用;中,但也有同样的问题。反正有没有第一次调用的效果被保存?

4

2 回答 2

9

这就是system工作原理:它创建一个子shell 来执行您的命令,当命令完成时,子shell 退出,您的perl进程不受影响。

Perl FAQ 的第 8 节也回答了这个问题。

我在 perl 脚本中{更改了目录,修改了我的环境}。当我退出脚本时,更改为什么消失了?如何让我的更改可见?

  • Unix

从最严格的意义上说,它是无法完成的——脚本作为与其启动时所在的 shell 不同的进程执行。对流程的更改不会反映在其父进程中 - 只会反映在更改后创建的任何子进程中。有一种 shell 魔法可以让你通过eval()在 shell 中输入脚本的输出来伪造它;查看comp.unix.questions 常见问题以了解详细信息。

你想要代码

system("cd /home/project/env/NeededEnvironment && make cfile.o") == 0
  or warn "$0: make failed";

或使用-C选项来make避免 shell 参数解析,如

system("make", "-C", "/home/project/env/NeededEnvironment", "cfile.o") == 0
  or warn "$0: make failed";
于 2013-07-17T14:37:55.177 回答
7

如果您正在编写 Perl 脚本,请尽可能少地使用 Perl 本身和外壳。

如果您需要更改目录:

chdir 'some/other/dir';

如果需要设置环境变量:

$ENV{ SOME_VAR } = 'Some value';

更新

以下是一些不应使用等效 shell 的命令:

  • mkdir
  • unlink
  • rmdir

每个人都应该知道的模块:

  • File::Copy
  • File::Path
  • File::Basename
  • File::Spec
于 2013-07-17T14:40:36.493 回答