通过系统修改过程环境的持久影响

Nic*_*ein 3 perl

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

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

 system("setenv home/project/env/NeededEnvironment");
 system("make cfile.o");
Run Code Online (Sandbox Code Playgroud)

第二个系统调用不知道第一次调用设置文件编译所需的环境.我已经尝试将它们分成一个系统调用;,但也有相同的问题.反正有没有得到保存的第一个电话的效果?

Gre*_*con 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";
Run Code Online (Sandbox Code Playgroud)

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

system("make", "-C", "/home/project/env/NeededEnvironment", "cfile.o") == 0
  or warn "$0: make failed";
Run Code Online (Sandbox Code Playgroud)


inn*_*naM 7

如果您正在编写Perl脚本,请尽可能少地使用Perl本身和shell-out.

如果您需要更改目录:

chdir 'some/other/dir';
Run Code Online (Sandbox Code Playgroud)

如果需要设置环境变量:

$ENV{ SOME_VAR } = 'Some value';
Run Code Online (Sandbox Code Playgroud)

更新

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

  • mkdir
  • unlink
  • rmdir

每个人应该知道的模块:

  • File::Copy
  • File::Path
  • File::Basename
  • File::Spec

  • +1表示"尽可能少地出壳",有明显的例子 (2认同)
  • 您应该测试`chdir`(或任何系统调用)是否成功,并在失败时提供有用的警告. (2认同)
  • 此外,还有用于操作文件和目录路径的`File :: Basename`和`File :: Spec`. (2认同)