2010-11-19 15 views
8

estoy usando una llamada al sistema para hacer algunas tareas¿Qué shell usa una llamada a Perl system()?

system('myframework mycode'); 

pero se queja de la falta de variables de entorno. Esas variables de entorno están establecidas en mi shell bash (desde donde ejecuto el código Perl).

¿Qué estoy haciendo mal?

¿La llamada system crea un nuevo shell (sin configuración de variables de entorno)? ¿Cómo puedo evitar eso?

Respuesta

17

Es complicado. Perl no necesariamente invoca un shell. Perldoc dice:

Si sólo hay un argumento escalar, el argumento se comprueba la metacaracteres de shell, y si los hay, todo el argumento se pasa al intérprete de comandos del sistema para el análisis (esto es/bin/sh -c en plataformas Unix, pero varía en otras plataformas). Si no hay metacaracteres de shell en el argumento, se divide en palabras y se pasa directamente a execvp, que es más eficiente.

Así que en realidad parece que tendría los argumentos pasados ​​directamente a execvp. Además, si el shell cargó su .bashrc, .profile o .bash_profile depende de si el shell es interactivo. Probablemente no lo es, pero puede marcar como this.

3

sistema() llamadas/bin/sh como shell. Si se encuentra en una caja algo diferente, como ARM, sería bueno leer la página man para la familia de llamadas ejecutivas: comportamiento predeterminado. Puede invocar su .profile si es necesario, ya que el sistema() recibe un comando

system(" . myhome/me/.profile && /path/to/mycommand") 
0

tratar system("echo \$SHELL"); en su sistema.

+1

Esto está mal. 'system' call NO respeta $ SHELL de ninguna manera, forma o forma. Ver la respuesta de Matt Kane – DVK

3

Si no desea invocar una concha, llame system con una lista:

system 'mycommand', 'arg1', '...'; 
system qw{mycommand arg1 ...}; 

Si desea una carcasa específica, lo llaman de forma explícita:

system "/path/to/mysh -c 'mycommand arg1 ...'"; 
4

Creo que no es la cuestión de la elección del shell, ya que las variables de entorno son siempre heredadas por subprocesos a menos que se limpien explícitamente. ¿Estás seguro de que has exportado tus variables? Esto funcionará:

$ A=5 perl -e 'system(q{echo $A});' 
5 
$ 

Esto también funcionará:

$ export A=5 
$ perl -e 'system(q{echo $A});' 
5 
$ 

Esto no lo haría:

$ A=5 
$ perl -e 'system(q{echo $A});' 

$ 
1

Ensucié con variables de entorno se establecen para mi guión en donde this post necesitaba la variable env $ DBUS_SESSION_BUS_ADDRESS para ser configurada, pero no lo haría cuando llamé al script como root. Puede leerlo, pero al final puede verificar si% ENV contiene las variables que necesita y si no las agrega.

De perlvar

%ENV 
    $ENV{expr} 
      The hash %ENV contains your current environment. Setting a value in "ENV" changes 
      the environment for any child processes you subsequently fork() off. 

Mi problema era que yo estaba corriendo el guión bajo sudo y que no ha conservado todas las variables env de mi usuario, ¿Está ejecutando el guión bajo sudo o como algunos otro usuario, decir www-data (apache)?

Prueba simple:

[email protected]:~$ perl -e 'print $ENV{q/MY_ENV_VARIABLE/} . "\n"' 

y si eso no funciona, entonces tendrá que añadirlo a ENV% en la parte superior de su script.

2

He luchado durante 2 días trabajando en esto. En mi caso, las variables de entorno se configuraron correctamente en Linux pero no en cygwin.

De mkb's respuesta Pensé que echa un vistazo a man perlrun y menciona una variable llamada PERL5SHELL. El entonces siguiendo resuelto el problema:

$ENV{PERL5SHELL} = "sh"; 

Como suele ser el caso - todo lo que puedo decir es "funciona para mí", aunque la documentación no implica que esto podría ser una solución sensata:

Puede establecerse en un shell alternativo que perl debe usar internamente para ejecutar comandos "backtick" o system().

Si el shell utilizado por perl no hereda implícitamente las variables de entorno, entonces no se establecerán para usted.

Cuestiones relacionadas