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 № 1Z 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
zamiast0755
.
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;