exec 'cat -n /etc/passwd'; die "no se pudo ejecutar cat: $!";
La nueva tarea tendrá exactamente el mismo PID que el programa Perl:
pp2@nereida:~/src/perl$ cat exec1.pl #!/usr/local/bin/perl -w use strict; print "$$\n"; exec '/bin/echo $$' pp2@nereida:~/src/perl$ exec1.pl 8422 8422
Al igual que con system, si se usa la sintáxis con lista de argumentos los metacaracteres shell no son interpretados.
$ cat exec.pl #!/usr/bin/perl -w exec '/bin/echo', 'Los argumentos son: ', @ARGV;Al ejecutar protegemos los argumentos con comillas simples de su interpretación por la shell:
lhp@nereida:~/Lperl/src$ ./exec.pl 'uno' '| ls ' '| who > quien' Los argumentos son: uno | ls | who > quien
source
cuando queremos modificar las variables de entorno
comandos desde un fichero de comandos.
Suelo usar las funciones exec
y system
de Perl cuando tengo
que crear dinámicamente el programa a ejecutar o tengo
que establecer un entorno de trabajo complicado antes de la ejecución de un programa existente.
Este es un fragmento de una rutina que envuelve la ejecución desacoplada de un programa
para su ejecución en una máquina remota vía SSH:
sub wrapexec { my $exec = shift; my $dir = getcwd; my $program =<< 'EOPROG'; chdir "<<$dir>>" || die "Can't change to dir <<$dir>>\n"; %ENV = (<<$ENV>>); $| = 1; my $success = !system("<<$exec>>"); warn "GRID::Machine::Core::wrapexec warning!. Execution of '<<$exec>>' returned Status: '$?'.". " Success value from system call: '$success'\n" unless $success; unlink('<<$scriptname>>'); exit(0); EOPROG $exec =~ /^\s*(\S+)/; # mmm.. no options? my $execname = $1; # Executable can be in any place of the PATH search my $where = `which $execname 2>&1`; # skip if program 'which' can't be found otherwise check that $execname exists unless ($?) { die "Error. Can't find executable for command '$execname'.". " Where: '$where'\n" unless $execname && $where =~ /\S/; } # name without path my ($name) = $execname =~ m{([\w.]+)$}; $name ||= ''; my $ENV = "'".(join "',\n '", %ENV)."'"; # Create a temp perl script with pattern /tmp/gridmachine_driver_${name}XXXXX my $filename = "gridmachine_driver_${name}"; my $tmp = File::Temp->new( TEMPLATE => $filename.'XXXXX', DIR => File::Spec->tmpdir(), UNLINK => 0); my $scriptname = $tmp->filename; $program =~ s/<<\$dir>>/$dir/g; $program =~ s/<<\$ENV>>/$ENV/g; $program =~ s/<<\$exec>>/$exec/g; $program =~ s/<<\$scriptname>>/$scriptname/g; print $tmp $program; close($tmp); return $scriptname; }
En http://www.perlmonks.org/ apareció la siguiente pregunta (busque por el tópico calling Unix commands):
Hi, I'm trying write a script that will call a unix comand and either post the results or parse the results then post them. I thought perhaps I could accomplish this with exec or system. However, I haven't been able to figure it out. Any insight would be much appreciated. ThanxComente las respuestas. Estudie el módulo Shell y discuta su implementación.
Explique la salida:
pp2@nereida:~/Lbook$ perl -wde 0 main::(-e:1): 0 DB<1> use Shell qw(echo cat ps cp) DB<2> s $foo = echo("howdy", "funny", "world") main::((eval 7)[/usr/share/perl/5.8/perl5db.pl:628]:3): 3: $foo = echo("howdy", "funny", "world"); DB<<3>> s Shell::AUTOLOAD(/usr/share/perl/5.8/Shell.pm:132): 132: shift if ref $_[0] && $_[0]->isa( 'Shell' ); DB<<3>> n Shell::AUTOLOAD(/usr/share/perl/5.8/Shell.pm:133): 133: my $cmd = $AUTOLOAD; DB<<3>> Shell::AUTOLOAD(/usr/share/perl/5.8/Shell.pm:134): 134: $cmd =~ s/^.*:://; DB<<3>> p $cmd Shell::echo DB<<4>> n Shell::AUTOLOAD(/usr/share/perl/5.8/Shell.pm:136): 136: *$AUTOLOAD = _make_cmd($cmd); DB<<4>> n Shell::AUTOLOAD(/usr/share/perl/5.8/Shell.pm:137): 137: goto &$AUTOLOAD; DB<<4>> x @_ 0 'howdy' 1 'funny' 2 'world' DB<<5>> c DB<6> p $foo howdy funny world