Pergunta

I have a Perl script which needs to be called from a clean environment. The way I call the script is as follows.

env -i test.pl

After invoking env -i, certain environment variables are left intact, such as PATH. However, according to the ENV hash, the PATH variable is empty.

Here is the script (abridged):

#!/usr/bin/perl -w

system('echo "system: $PATH"');
print "perl hash: $ENV{'PATH'}\n";

This is the output when I run env -i test.pl:

system: /usr/local/bin:/bin:/usr/bin
Use of uninitialized value in concatenation (.) or string at test.pl line 4.
perl hash:

How can I get the ENV hash to be correct when I invoke the script under env -i?

Foi útil?

Solução

The -i option to env does in fact clear $PATH out of the environment. The reason you see inconsistent results from the system call is because of how system works:

If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is /bin/sh -c on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to execvp , which is more efficient.

Because you are calling system with a single commandline that must be parsed by a shell, one is started, which initializes its own $PATH upon startup (because shells do that), and that's the one you're seeing.

Outras dicas

After invoking env -i, certain environment variables are left intact, such as PATH. However, according to the ENV hash, the PATH variable is empty.

On my rhel system, env -i does:

    -i, --ignore-environment
          start with an empty environment

So when you run the Perl program, the system() call is forking a shell, whic is probably reading an rc file that is setting PATH. but when you print $ENV{PATH} directly form the Perl program, it is empty as expected.

You should either manually set PATH, or determine the full paths to the various executables that you intend to run.

If you're going to spend a lot of time running system() commands, then maybe a shell script, with some Perl to process intermediate results is a better processing model in this case.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top