2013-08-14 18 views
5

Mam problem z uzyskaniem wartości zwracanej przez polecenie unix do zmiennej perl.Jak poprawnie uchwycić zwracaną wartość polecenia unix?

Unix poleceń:

#nc -z 8.8.8.8 441; echo $? 
1 

Perl polecenie:

#perl -e 'my $pstate=`nc -z 8.8.8.8 441; echo $?`; print $pstate;' 
0 

Więc wydaje polecenie Perl, aby uzyskać wartości zwracanej "bez błędów"? Jak poprawnie uchwycić zwracaną wartość polecenia * nix?

Inny przykład:

#perl -e 'my $pstate=`ping -v 8.8.8.8 -c 1`; print $pstate;' 
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 

ta zwraca odpowiednią wartość. Co więc robię źle w pierwszej kolejności?

Odpowiedz

9

zmienne są interpolowane wewnątrz backticks, tak $? w

my $pstate=`nc -z 8.8.8.8 441; echo $?` 

dotyczy Perl $? nie w powłoce $?. A co powłoka widzi coś takiego jak

nc -z 8.8.8.8 441 ; echo 0 

Aby rozwiązać ten problem, można uciec polecenia Shell

my $pstate=`nc -z 8.8.8.8 441; echo \$?`; 

lub użyć operatora qx z pojedynczy cudzysłów jako separator (to jest jeden wyjątek w „interpolacji wewnątrz operatora qx” zasada)

my $pstate=qx'nc -z 8.8.8.8 441; echo $?'; 

, lub readpipe z nie interpolowane cytując konstr cja

my $pstate= readpipe('nc -z 8.8.8.8 441; echo $?'); 
my $pstate= readpipe(q{nc -z 8.8.8.8 441; echo $?}); 
+0

+1 za readpipe –

+0

Ah. Założę się, że pojedyncze cudzysłowy uciekną przed '?' – Droidzone

+0

Są one zwrotnymi, które różnią się od pojedynczych cudzysłowów. – mob

1

Innym sposobem, aby to zrobić jest użycie IPC::Run3 który "pozwala uruchomić podproces i przekierować stdin, stdout i/lub stderr do plików i Perl struktury danych".

Podobny do systemu, możesz sprawdzić $? potem na różne sposoby, w tym poprzez przesunięcie 8, aby uzyskać rzeczywisty kod wyjścia tak:

if ($? == -1) { 
print "failed to execute: $!\n"; 
} 
elsif ($? & 127) { 
printf "child died with signal %d, %s coredump\n", 
($? & 127), ($? & 128) ? 'with' : 'without'; 
} 
else { 
printf "child exited with value %d\n", $? >> 8; 
} 

Ten blok jest wzięte z dokumentacji systemowej tutaj http://perldoc.perl.org/functions/system.html który wspomina także co devnull powiedział. Za każdym razem, gdy zależy mi na czymś więcej niż tylko na qx lub systemie, przełączam się na IPC :: Run3, ponieważ ułatwia to uzyskanie wszystkiego.

Powiązane problemy