Ruby Language
Operativsystem eller Shell-kommandon
Sök…
Introduktion
Det finns många sätt att interagera med operativsystemet. Inifrån Ruby kan du köra skal / systemkommandon eller delprocesser.
Anmärkningar
Exec:
Exec har mycket begränsad funktionalitet och när den körs kommer den att lämna Ruby-programmet och köra kommandot.
Systemkommandot:
Systemkommandot körs i ett sub-skal istället för att ersätta den aktuella processen och returnerar true eller nill. Systemkommandot är, liksom backticks, en blockeringsoperation där huvudapplikationen väntar tills resultatet av systemoperationen är klar. Här behöver huvudoperationen aldrig oroa sig för att fånga ett undantag från barnprocessen.
Utgången från systemfunktionen kommer alltid att vara sant eller noll beroende på om skriptet har utförts utan fel. Därför kommer varje fel vid körning av skript inte att skickas till vår applikation. Huvudoperationen behöver aldrig oroa sig för att fånga ett undantag från barnprocessen. I detta fall är utgången noll eftersom barnprocessen skapade ett undantag.
Detta är en blockerande operation där Ruby-programmet kommer att vänta tills kommandot har slutförts innan det pågår.
Systemoperationen använder gaffel för att gaffla den aktuella processen och sedan utföra den givna operationen med exec.
Ryggstickarna (`):
Backtick-karaktären finns vanligtvis under escape-tangenten på tangentbordet. Backticks körs i ett sub-shell i stället för att ersätta den aktuella processen och returnerar resultatet av kommandot.
Här kan vi få kommandot utdata men programmet kraschar när ett undantag genereras.
Om det finns ett undantag i delprocessen ges det undantaget huvudprocessen och huvudprocessen kan avslutas om undantag inte hanteras. Detta är en blockerande operation där Ruby-programmet väntar tills kommandot har slutförts innan det pågår.
Systemoperationen använder gaffel för att gaffla den aktuella processen och sedan utföra den givna operationen med exec.
IO.popen:
IO.popen körs i en delprocess. Här ansluts delprocessens standardingång och standardutgång till IO-objektet.
Popen3:
Popen3 ger dig tillgång till standardingång, standardutgång och standardfel.
Delprocessens standardinmatning och -utgång kommer att returneras till IO-objekt.
$? (samma som $ CHILD_STATUS)
Kan användas med backticks, system () eller% x {} operationer och ger status för det sista system exekverade kommandot.
Detta kan vara användbart för att komma åt exitstatus
och pid
egenskaperna.
$?.exitstatus
Rekommenderade sätt att köra skalkod i Ruby:
Open3.popen3 eller Open3.capture3:
Open3 använder faktiskt bara Rubys spawn-kommando, men ger dig ett mycket bättre API.
Open3.popen3
Popen3 körs i en delprocess och returnerar stdin, stdout, stderr och wait_thr.
require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5s && ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"
eller
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
kommer att matas ut: stdout är: stderr är: dödligt: Inte ett git-arkiv (eller något av moderkatalogerna): .git
eller
require 'open3'
cmd = 'ping www.google.com'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
while line = stdout.gets
puts line
end
end
kommer att mata ut:
Pinging www.google.com [216.58.223.36] med 32 byte data:
Svar från 216.58.223.36: bytes = 32 tid = 16ms TTL = 54
Svar från 216.58.223.36: bytes = 32 tid = 10ms TTL = 54
Svar från 216.58.223.36: bytes = 32 tid = 21ms TTL = 54
Svar från 216.58.223.36: bytes = 32 tid = 29ms TTL = 54
Pingstatistik för 216.58.223.36:
Paket: Skickat = 4, Mottaget = 4, Förlorat = 0 (0% förlust),
Ungefärliga rundturstider i milli-sekunder:
Minsta = 10ms, Maximum = 29ms, medelvärde = 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
eller
Open3.capture3('/some/binary with some args')
Rekommenderas dock inte på grund av ytterligare omkostnader och potentialen för skalinjektioner.
Om kommandot läser från stdin och du vill mata det lite data:
Open3.capture3('my_funky_command', stdin_data: 'read from stdin')
Kör kommandot med en annan arbetskatalog med chdir:
Open3.capture3('my_funky_command', chdir: '/some/directory')
Klassiska sätt att köra skalkod i Ruby:
Exec:
exec 'echo "hello world"'
eller
exec ('echo "hello world"')
Systemkommandot:
system 'echo "hello world"'
Skickar ut "hej värld" i kommandofönstret.
eller
system ('echo "hello world"')
Systemkommandot kan returnera ett sant om kommandot var framgångsrikt eller noll när inte.
result = system 'echo "hello world"'
puts result # will return a true in the command window
Ryggstickarna (`):
echo "hello world"
Skickas ut "hej värld" i kommandofönstret.
Du kan också fånga resultatet.
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 }