/ / najlepszy sposób na wykonanie komend unix w skrypcie perla i sprawdzenie, czy nie powiodło się - perl

najlepszy sposób na wykonywanie poleceń uniksowych w skrypcie perla i sprawdzanie, czy się nie udało - perl

Chcę wykonać kilka poleceń Uniksaw perlu. Jaki jest najlepszy sposób na to? Czy lepiej jest używać qx lub system ()? Czy istnieje dobry sposób sprawdzenia, czy nie powiedzie się? Czy ktoś może mi pokazać dobry przykład? Dzięki.

my $crflag=qx("/bin/touch /tmp/flag.done");
my $chgperm=qx("chmod 755 /tmp/flag.done");

vs.

my $crflag = "/bin/touch /tmp/flag.done";
my $chgperm ="chmod 755 /tmp/flag.done";
system ($crflag);
system ($chgperm);

Odpowiedzi:

5 dla odpowiedzi № 1

Z twoim kodem jest kilka problemów:

  • Wydaje się, że nie chcesz wyjścia, co oznacza, że ​​chcesz system, ale są to bardzo proste kroki i powinny być wykonywane bezpośrednio w Perlu, zamiast wywoływać powłokę. touch jest dosłownie 1 wywołaniem w Perlu (2, jeśli liczysz zamknięcie pliku).
  • Jest sytuacja wyścigowa, odkąd tworzyszplik, a następnie ustaw jego uprawnienia w dwóch krokach. Ponieważ wygląda to jak plik flagowy, warunek wyścigu wydaje się istotny i dlatego prawdopodobnie chcesz, aby atomowe tworzenie / ustawianie w jednym poleceniu.
  • Ponieważ to flaga plik, prawdopodobnie chcesz trybu 0644 zamiast 0755.

W Perlu możesz rozwiązać wszystkie powyższe rzeczy za pomocą czegoś takiego:

#!/usr/bin/perl

use Fcntl qw( :DEFAULT );   # Core module, for O_CREAT, etc. constants
use strict;
use warnings;

# You probably want 0644, as a flag file probably shouldn"t be executable..?
sysopen( my $fh, "/tmp/flag.done", O_CREAT|O_EXCL|O_RDWR, 0644 )
# Sysopen returns a undef if unsuccessful, with an error message stored in $!
or die "$!";
# write to it here, if you need to.
close( $fh );

Możesz umieścić to w subwoodzie z czymkolwiekargumenty, które chcesz utworzyć (o wiele więcej) atomowego kroku tworzenia, aby uniknąć innych procesów zakłócających dużą liczbę wywołań do dwukrotnego wyskakiwania w celu utworzenia pliku, a następnie zresetowania jego uprawnień. (Nadal istnieją problemy z synchronizacją, więc nadal można ją wyprzedzić, ale ogólnie jest to znacznie lepsze rozwiązanie.)

Istnieją inne flagi, których możesz użyć. Czek perldoc perlopentut i wyszukaj sysopen na małą listę lub sprawdź perldoc Fcntl i dokumentację twojej platformy, aby uzyskać bardziej wyczerpującą listę. Możesz także zmienić 0644 uprawnienia do czegoś bardziej i mniej restrykcyjnego, a ponadto możesz chcieć użyć blokowania; widzieć perldoc -f flock po informacje i przykłady kodu dotyczące blokowania doradczego.


4 dla odpowiedzi nr 2

Poza tym, że obie operacje można wykonać trywialnie, używając wbudowanych utime i chmod, IPC :: System :: Simple zapewnia sprawdzanie błędów.

use IPC::System::Simple qw( system );
system("/bin/touch /tmp/flag.done");
system("chmod 755 /tmp/flag.done");

2 dla odpowiedzi nr 3

Posługiwać się system wraz z $?. Staraj się unikać używania qx gdy wyjście nie jest wymagane.

system "/bin/touch /tmp/flag.done";
my $touch_status = $? >> 8;

system "chmod 755 /tmp/flag.done";
my $chmod_status = $? >> 8;