Ruby Weblog

Winfried Mueller
www.reintechnisch.de

Wer Skriptsprachen und Objektorientierung mag, findet in Ruby eine ästhetische Ausdrucksmöglichkeit seines Könnens. Plattformübergreifend.


09.02.2007 Ein paar Utilities

Permalink

Die letzten Tage habe ich an einigen Utilities gebastelt, die mir das Leben als Admin erleichtern.

md5check ist ein Programm, mit dem ich über ein komplettes Verzeichnis hinweg von allen Dateien md5-Checksummen bilde. Das Resultat kann man in einer Datei speichern. Später kann man hierüber vergleichen, welche Dateien sich verändert haben. Das Programm funktioniert sowohl unter Windows wie unter Linux.

lbackup ist ein Programm zur Datensicherung unter Linux. Bei mir läuft es unter Ubuntu Dapper.

dpkgcheck ist ein Paketmanagment Hilfswerkzeug für Ubuntu/Debian Rechner, die dpkg als Paketmanagment einsetzen. Hiermit kann man z.B. einen Snapshot der installierten Pakete machen, um später Veränderungen aufzuspüren. Oder um auf einem anderen Rechner die Paketinstallation abzugleichen.

06.01.2007 Fehler in popen3

Permalink

Die Kommunikation zwischen externen Programmen und Ruby ist manchmal nicht so trivial. Neben den Backticks gibt es ja noch system(), popen() und popen3(). Ich habe gerade einige Tests mit popen3 gemacht. Ich wollte ein externes Programm aufrufen und mir stdout und stderr getrennt zurückgeben lassen. Das funktionierte auch schonmal recht gut:

 
require( "open3" )

stream_error = ""
stream_std = ""
cmd = "/bin/date"

Open3.popen3( cmd ) do |stdin, stdout, stderr|
  stream_std = stdout.readlines.join( "" )
  stream_error   = stderr.readlines.join( "" )
end

puts "stream_error: "
puts stream_error
puts
puts "stream_std: "
puts stream_std

Ein Problem gibt es allerdings. Der Exitstatus ist nicht korrekt, wie dieser Test zeigt:

 
require( "open3" )

stream_error = ""
stream_std = ""
cmd = "/bin/false"
Open3.popen3( cmd ) do |stdin, stdout, stderr|
  stream_std = stdout.readlines.join( "" )
  stream_error   = stderr.readlines.join( "" )
end

# Exitstatus zurückgeben
puts $?

Er ist immer 0. Leider ist das ein unschöner Bug, der bereits seit über 3 Jahren existiert. Leider ist dieser technisch bedingt, wie Matz schreibt: open3 uses the "double fork" technique, so that you cannot take the exit status of the command.

Bei popen hingegen soll es korrekt funktionieren. Bleibt zu hoffen, dass man das technisch mal so implementiert, dass der Exitstatus erhalten bleibt. Andere Skriptsprachen können das ja auch.

Nachtrag: Nun hab ich doch eine Lösung gefunden: Open4 kann es. Sie wurde dafür gebaut, um genau dieses Problem zu lösen. Leider gehört Open4 aber nicht zur Standardbibliothek. Mit "gem install open4" ist das Teil aber schnell nachinstalliert.

Beispiel:

 
require( "rubygems" )
require( "open4" )

stream_error = ""
stream_std = ""
cmd = "/bin/false"

Open4.popen4( cmd ) do |pid, stdin, stdout, stderr|
  stream_std = stdout.readlines.join( "" )
  stream_error   = stderr.readlines.join( "" )
end

puts "stream_error: "
puts stream_error
puts
puts "stream_std: "
puts stream_std

print "Exitstatus: "
puts ($?.to_i >> 8).to_s

Weblinks:


<< Aktuell | RubyWeblog | Archiv 2006 >>