output = `program args` # collect output into one multiline string output = `program args`.to_a # collect output into array, one line per element output = "" IO.popen("ls") do |readme| readme.each do |line| output << line end end `fsck -y /dev/rsd1a` # BAD AND SCARY in Perl because it's managed by the shell # I donna in Ruby ... # so the "clean and secure" version readme, writeme = IO.pipe pid = fork { # child $stdout.reopen writeme readme.close exec('find', '..') } # parent writeme.close readme.each do |line| # do something with 'line' end Process.waitpid(pid) |
status = system("xemacs #{myfile}") status = system("xemacs", myfile) system("cmd1 args | cmd2 | cmd3 >outfile") system("cmd args <infile >outfile 2>errfile") # stop if the command fails abort "$program exited funny: #{$?}" unless system("cmd", "args1", "args2") # get the value of the signal sent to the child # even if it is a SIGINT or SIGQUIT arglist = ['ruby', '-e', '5.times {|i| p i}'] system(*arglist) raise "program killed by signal #{$?}" if ($? & 127) != 0 pid = fork { trap("SIGINT", "IGNORE") exec("sleep", "10") } trap ("SIGINT") { puts "Tsk tsk, no process interruptus" } Process.waitpid(pid, 0) # Ruby permits to lie to the program called by a 'system'. # (ie specify what return argv[0] in C, $0 in Perl/Ruby ...) system ['bash', 'fake'], '-c', 'echo $0' |
exec("archive *.data") exec("archive", "accounting.data") exec("archive accounting.data") |
# read the output of a program IO.popen("ls") {|readme| while readme.gets do # ... end } # or readme = IO.popen("ls") while readme.gets do # ... end readme.close # "write" in a program IO.popen("cmd args","w") {|pipe| pipe.puts("data") pipe.puts("foo") } # close wait for the end of the process read = IO.popen("sleep 10000") # child goes to sleep read.close # and the parent goes to lala land writeme = IO.popen("cmd args", "w") writeme.puts "hello" # program will get hello\n on STDIN writeme.close # program will get EOF on STDIN # send in a pager (eg less) all output $stdout = IO.popen("/usr/bin/less","w") print "huge string\n" * 10000 |
#----------------------------- def head(lines = 20) pid = open("|-","w") if pid == nil return else while gets() do pid.print lines -= 1 break if lines == 0 end end exit end head(100) while gets() do print end #----------------------------- 1: > Welcome to Linux, version 2.0.33 on a i686 2: > 3: > "The software required `Windows 95 or better', 4: > so I installed Linux." #----------------------------- > 1: Welcome to Linux, Kernel version 2.0.33 on a i686 > 2: > 3: "The software required `Windows 95 or better', > 4: so I installed Linux." #----------------------------- #!/usr/bin/ruby # qnumcat - demo additive output filters def number() pid = open("|-","w") if pid == nil return else while gets() do pid.printf("%d: %s", $., $_); end end exit end def quote() pid = open("|-","w") if pid == nil return else while gets() do pid.print "> #{$_}" end end exit end number() quote() while gets() do print end $stdout.close exit |
ARGV.map! { |arg| arg =~ /\.(gz|Z)$/ ? "|gzip -dc #{arg}" : arg } for file in ARGV fh = open(file) while fh.gets() do # ....... end end #----------------------------- ARGV.map! { |arg| arg =~ %r#^\w+://# ? "|GET #{arg}" : arg # } for file in ARGV fh = open(file) while fh.gets() do # ....... end end #----------------------------- pwdinfo = (`domainname` =~ /^(\(none\))?$/) ? '/etc/passwd' : '|ypcat passwd'; pwd = open(pwdinfo); #----------------------------- puts "File, please? "; file = gets().chomp(); fh = open(file); |
output = `cmd 2>&1` # with backticks # or ph = open("|cmd 2>&1") # with an open pipe while ph.gets() { } # plus a read #----------------------------- output = `cmd 2>/dev/null` # with backticks # or ph = open("|cmd 2>/dev/null") # with an open pipe while ph.gets() { } # plus a read #----------------------------- output = `cmd 2>&1 1>/dev/null` # with backticks # or ph = open("|cmd 2>&1 1>/dev/null") # with an open pipe while ph.gets() { } # plus a read #----------------------------- output = `cmd 3>&1 1>&2 2>&3 3>&-` # with backticks # or ph = open("|cmd 3>&1 1>&2 2>&3 3>&-") # with an open pipe while ph.gets() { } # plus a read #----------------------------- system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr") #----------------------------- output = `cmd 3>&1 1>&2 2>&3 3>&-` #----------------------------- fd3 = fd1 fd1 = fd2 fd2 = fd3 fd3 = undef #----------------------------- system("prog args 1>tmpfile 2>&1") system("prog args 2>&1 1>tmpfile") #----------------------------- # system ("prog args 1>tmpfile 2>&1") fd1 = "tmpfile" # change stdout destination first fd2 = fd1 # now point stderr there, too #----------------------------- # system("prog args 2>&1 1>tmpfile") fd2 = fd1 # stderr same destination as stdout fd1 = "tmpfile" # but change stdout destination #----------------------------- # It is often better not to rely on the shell, # because of portability, possible security problems # and bigger resource usage. So, it is often better to use the open3 library. # See below for an example. # opening stdin, stdout, stderr require "open3" stdin, stdout, stderr = Open3.popen('cmd') |
#----------------------------- # Contrary to perl, we don't need to use a module in Ruby fh = Kernel.open("|" + program, "w+") fh.puts "here's your input\n" output = fh.gets() fh.close() #----------------------------- Kernel.open("|program"),"w+") # RIGHT ! #----------------------------- # Ruby has already object methods for I/O handles #----------------------------- begin fh = Kernel.open("|" + program_and_options, "w+") rescue if ($@ ~= /^open/) $stderr.puts "open failed : #{$!} \n #{$@} \n" break end raise # reraise unforseen exception end |
#% kill -l #HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE #ALRM TERM CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM #PROF WINCH POLL PWR #----------------------------- #% ruby -e 'puts Signal.list.keys.join(" ")' #PWR USR1 BUS USR2 TERM SEGV KILL POLL STOP SYS TRAP IOT HUP INT # #WINCH XCPU TTIN CLD TSTP FPE IO TTOU PROF CHLD CONT PIPE ABRT #VTALRM QUIT ILL XFSZ URG ALRM #----------------------------- # After that, the perl script create an hash equivalent to Signal.list, # and an array. The array can be obtained by : signame = [] Signal.list.each { |name, i| signame[i] = name } |
Process.kill(9, pid) # send $pid a signal 9 Process.kill(-1, Process.getpgrp()) # send whole job a signal 1 Process.kill("USR1", $$) # send myself a SIGUSR1 Process.kill("HUP", pid1, pid2, pid3) # send a SIGHUP to processes in @pids #----------------------------- begin Process.kill(0, minion) puts "#{minion} is alive!" rescue Errno::EPERM # changed uid puts "#{minion} has escaped my control!"; rescue Errno::ESRCH puts "#{minion} is deceased."; # or zombied rescue puts "Odd; I couldn't check the status of #{minion} : #{$!}" end |
Kernel.trap("QUIT", got_sig_quit) # got_sig_quit = Proc.new { puts "Quit\n" } trap("PIPE", "got_sig_quit") # def got_sig_pipe ... trap("INT") { ouch++ } # increment ouch for every SIGINT #----------------------------- trap("INT", "IGNORE") # ignore the signal INT #----------------------------- trap("STOP", "DEFAULT") # restore default STOP signal handling |
# the signal handler def ding trap("INT", "ding") puts "\aEnter your name!" end # prompt for name, overriding SIGINT def get_name save = trap("INT", "ding") puts "Kindly Stranger, please enter your name: " name = gets().chomp() trap("INT", save) name end |
# implemented thanks to http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/1760 require 'timeout' # we'll do something vastly more useful than cookbook to demonstrate timeouts begin timeout(5) { waitsec = rand(10) puts "Let's see if a sleep of #{waitsec} seconds is longer than 5 seconds..." system("sleep #{waitsec}") } puts "Timeout didn't occur" rescue Timeout::Error puts "Timed out!" end |