ruby system komut kontrol çıkış kodu


106

Ruby'de aşağıdaki gibi bir dizi sistem çağrım var ve çıkış kodlarını aynı anda kontrol etmek istiyorum, böylece bu komut başarısız olursa betiğimin çıkması.

system("VBoxManage createvm --name test1")
system("ruby test.rb")

Gibi bir şey istiyorum

system("VBoxManage createvm --name test1", 0) <- burada ikinci parametre çıkış kodunu kontrol eder ve bu sistem çağrısının başarılı olduğunu onaylar ve değilse, bir hata oluşturur veya bu tür bir şey yapar.

Bu mümkün mü?

Bu çizgide bir şey denedim ve bu da işe yaramadı.

system("ruby test.rb")
system("echo $?")

veya

`ruby test.rb`
exit_code = `echo $?`
if exit_code != 0
  raise 'Exit code is not zero'
end


Yukarıdaki örnekte, exit_codebir dizge olacak - ya "0\n"da "1\n", bu nedenle exit_code != 0her zaman doğru olacaktır
dgmstuart

Yanıtlar:


166

Gönderen belgeler :

truekomut sıfırdan farklı çıkış durumu falseiçin sıfır çıkış durumu verirse sistem geri döner . nilKomutun yürütülmesi başarısız olursa geri döner.

system("unknown command")     #=> nil
system("echo foo")            #=> true
system("echo foo | grep bar") #=> false

Ayrıca

İçinde bir hata durumu mevcuttur $?.

system("VBoxManage createvm --invalid-option")

$?             #=> #<Process::Status: pid 9926 exit 2>
$?.exitstatus  #=> 2

2
ve çıktısını (çıkış kodunu değil) bir değişkene nasıl yakalayabilirim?
ア レ ッ ク ス

Bir ray konsolundaysanız, bunu test edin, sadece $ değerini kaybedebileceğinizi unutmayın. bu yüzden REPL komutunuzun bir parçası olarak onu yakalamanız gerekiyor [10] pry(main)> system("touch /root/test 2> /dev/null") => false [11] pry(main)> $?.exitstatus => 0 [12] pry(main)> system("touch /root/test 2> /dev/null"); $?.exitstatus => 1
lardcanoe

Bir başka mükemmel karşılaştırma system, ters işaretler %xve execburada sağlanmıştır: stackoverflow.com/questions/6338908/…
Tom Harrison

38

Benim için, kabuk komutlarını çağırmak ve $? işlem durumunu almak için. $? bir işlem durumu nesnesidir, komutun işlem bilgilerini bu nesneden alabilirsiniz, bunlar arasında durum kodu, yürütme durumu, pid vb.

$ 'In bazı yararlı yöntemleri? nesne:

   $?.exitstatus => return error code    
   $?.success? => return true if error code is 0, otherwise false
   $?.pid => created process pid

1
Rubocop'un yardımıyla, okunabilir takma adının şu $?olduğunu $CHILD_STATUS
öğrendim

26

systemfalsekomut sıfır olmayan bir çıkış koduna nilsahipse veya komut yoksa döndürür .

Bu nedenle

system( "foo" ) or exit

veya

system( "foo" ) or raise "Something went wrong with foo"

çalışmalıdır ve makul ölçüde özlüdür.


6

Aramanızın sonucunu yakalamıyorsunuz system, bu da sonuç kodunun döndürüldüğü yerdir:

exit_code = system("ruby test.rb")

systemBacktick yöntemini içeren her çağrının veya eşdeğerinin yeni bir kabuk ortaya çıkardığını unutmayın, bu nedenle önceki bir kabuğun ortamının sonucunu yakalamak mümkün değildir. Bu durumda exit_code, trueher şey yolunda giderse, nilaksi halde.

popen3Komut daha düşük seviyeli ayrıntı sağlar.


2
Open3.capture3bu tür görevler için kullanımı özellikle kolay bir yöntemdir.
The Tin Man

6

Bunu yapmanın bir yolu, onları andveya kullanarak zincirlemektir &&:

system("VBoxManage createvm --name test1") and system("ruby test.rb")

İlk arama başarısız olursa ikinci arama yapılmayacaktır.

Size if ()biraz akış kontrolü sağlamak için bunları bir içine alabilirsiniz:

if (
  system("VBoxManage createvm --name test1") && 
  system("ruby test.rb")
) 
  # do something
else
  # do something with $?
end

Şimdiye kadar başarmak istediğim şey bu, yeterince açık ve net. Teşekkür ederim
mochadwi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.