Ruby Language
Besturingssysteem of Shell-opdrachten
Zoeken…
Invoering
Er zijn veel manieren om met het besturingssysteem te communiceren. Vanuit Ruby kunt u shell- / systeemopdrachten of subprocessen uitvoeren.
Opmerkingen
Exec:
Exec is zeer beperkt in functionaliteit en zal bij uitvoering het Ruby-programma verlaten en de opdracht uitvoeren.
Het systeem commando:
De opdracht System wordt uitgevoerd in een subshell in plaats van het huidige proces te vervangen en retourneert true of nill. De systeemopdracht is, net als backticks, een blokkeerbewerking waarbij de hoofdtoepassing wacht tot het resultaat van de systeembewerking is voltooid. Hier hoeft de hoofdoperatie zich nooit zorgen te maken over het vastleggen van een uitzondering uit het onderliggende proces.
De uitvoer van de systeemfunctie is altijd waar of nul, afhankelijk van of het script al dan niet zonder fouten is uitgevoerd. Daarom wordt elke fout tijdens het uitvoeren van het script niet doorgegeven aan onze applicatie. De hoofdoperatie hoeft zich nooit zorgen te maken over het vastleggen van een uitzondering uit het onderliggende proces. In dit geval is de output nul omdat het onderliggende proces een uitzondering heeft veroorzaakt.
Dit is een blokkeerbewerking waarbij het Ruby-programma wacht totdat de opdracht is voltooid voordat het doorgaat.
De systeembewerking gebruikt vork om het huidige proces te vorken en voert vervolgens de gegeven bewerking uit met exec.
De backticks (`):
Het backtick-personage bevindt zich meestal onder de escape-toets op het toetsenbord. Backticks wordt uitgevoerd in een subshell in plaats van het huidige proces te vervangen en retourneert het resultaat van de opdracht.
Hier kunnen we de uitvoer van de opdracht krijgen, maar het programma crasht wanneer een uitzondering wordt gegenereerd.
Als er een uitzondering in het subproces is, wordt die uitzondering aan het hoofdproces gegeven en kan het hoofdproces worden beëindigd als de uitzondering niet wordt afgehandeld. Dit is een blokkeerbewerking waarbij het Ruby-programma wacht totdat de opdracht is voltooid voordat het doorgaat.
De systeembewerking gebruikt vork om het huidige proces te vorken en voert vervolgens de gegeven bewerking uit met exec.
IO.popen:
IO.popen wordt uitgevoerd in een subproces. Hier worden de standaardinvoer en standaarduitvoer van het subproces verbonden met het IO-object.
Popen3:
Met Popen3 hebt u toegang tot de standaardinvoer, standaarduitvoer en standaardfout.
De standaard invoer en uitvoer van het subproces worden geretourneerd naar IO-objecten.
$? (hetzelfde als $ CHILD_STATUS)
Kan worden gebruikt met de backticks, system () of% x {} bewerkingen en geeft de status van de laatste door het systeem uitgevoerde opdracht.
Dit kan handig zijn om toegang te krijgen tot de exitstatus
en de pid
eigenschappen.
$?.exitstatus
Aanbevolen manieren om shell-code uit te voeren in Ruby:
Open3.popen3 of Open3.capture3:
Open3 gebruikt eigenlijk alleen Ruby's spawn-opdracht, maar geeft u een veel betere API.
Open3.popen3
Popen3 wordt uitgevoerd in een subproces en geeft stdin, stdout, stderr en wait_thr terug.
require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5s && ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"
of
require 'open3'
cmd = 'git push heroku master'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
puts "stdout is:" + stdout.read
puts "stderr is:" + stderr.read
end
will output: stdout is: stderr is: fataal: Geen git-repository (of een van de bovenliggende mappen): .git
of
require 'open3'
cmd = 'ping www.google.com'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
while line = stdout.gets
puts line
end
end
zal uitvoeren:
Pingelen van www.google.com [216.58.223.36] met 32 bytes aan gegevens:
Antwoord van 216.58.223.36: bytes = 32 tijd = 16ms TTL = 54
Antwoord van 216.58.223.36: bytes = 32 tijd = 10ms TTL = 54
Antwoord van 216.58.223.36: bytes = 32 tijd = 21ms TTL = 54
Antwoord van 216.58.223.36: bytes = 32 tijd = 29ms TTL = 54
Ping-statistieken voor 216.58.223.36:
Pakketten: Verzonden = 4, Ontvangen = 4, Verloren = 0 (0% verlies),
Geschatte reistijden in milliseconden:
Minimum = 10ms, Maximum = 29ms, Gemiddeld = 19ms
Open3.capture3:
require 'open3'
stdout, stderr, status = Open3.capture3('my_funky_command', 'and', 'some', 'argumants')
if status.success?
# command completed successfully, do some more stuff
else
raise "An error occured"
end
of
Open3.capture3('/some/binary with some args')
Niet aanbevolen, vanwege extra overhead en het potentieel voor shell-injecties.
Als het commando van stdin leest en u wilt het enkele gegevens invoeren:
Open3.capture3('my_funky_command', stdin_data: 'read from stdin')
Voer de opdracht uit met een andere werkmap, met behulp van chdir:
Open3.capture3('my_funky_command', chdir: '/some/directory')
Klassieke manieren om shell-code uit te voeren in Ruby:
Exec:
exec 'echo "hello world"'
of
exec ('echo "hello world"')
Het systeem commando:
system 'echo "hello world"'
Zal "hallo wereld" uitvoeren in het opdrachtvenster.
of
system ('echo "hello world"')
Het systeemcommando kan een true retourneren als het commando succesvol was of nul wanneer niet.
result = system 'echo "hello world"'
puts result # will return a true in the command window
De backticks (`):
echo "hello world"
Zal "hallo wereld" uitvoeren in het opdrachtvenster.
U kunt ook het resultaat bekijken.
result = `echo "hello world"`
puts "We always code a " + result
IO.popen:
# Will get and return the current date from the system
IO.popen("date") { |f| puts f.gets }