From: Brian Candler Date: 2009-10-27T18:27:10+09:00 Subject: Re: file open failure test Derek Smith wrote: > unless File.exists?( "#{RUNLOG}" ) > FileUtils.touch( "#{RUNLOG}" ) \ > || warn("Touch file failed for /var/log/prod_db_bkup.log!") > end 1. Why do you want to touch the file? You're going to write to it later anyway. Opening the file in mode "a" will create it if necessary. 2. If you do touch the file, why would you want to continue if it fails? If it does fail, you're almost bound to fail when you write to it anyway. > def log_mtd(arg) > File.open( "#{RUNLOG}", "a" ) do |file| > file.puts(arg) > end > end Looks OK - as pointed out, File.open(RUNLOG,"a") is sufficient. > def db_bkup(arg) > Dir.chdir( "#{DB_DIR}" ) \ > || die_mtd("Change_Dir_Failed_To_#{DB_DIR}_Dump_Will_Fail!") Dir.chdir will raise an exception if it fails, not return false/nil. So you could do something like this: def db_bkup(arg) begin Dir.chdir(DBDIR) rescue die_mtd "Change_Dir_Failed_To_#{DB_DIR}_Dump_Will_Fail!" end If you end up doing this a lot, you can write a helper function: def failex(msg) begin yield rescue die_mtd msg end end ... failex "Change_Dir_Failed_To_#{DB_DIR}_Dump_Will_Fail!" do Dir.chdir(DBDIR) end (Note: 'rescue' by itself captures StandardError and subclasses. If you want to catch absolutely all exceptions, use 'rescue Exception'. However this will also catch things like programming errors) But to be honest, this is not regular Ruby practice. You'd normally just write your script without error handling, and let the program fail. It will usually give a fairly obvious exception message itself. This is easy to try out in irb: >> Dir.chdir("/wibble") Errno::ENOENT: No such file or directory - /wibble from (irb):3:in `chdir' from (irb):3 So if your program gave that message, it would be fairly clear where the problem lies. > %x(echo ".dump"|sqlite3 development.sqlite3 |gzip -c > > "#{DB_BKUP.+(arg)}") \ > || die_mtd("SQL_Dump_Cmd_Failed.+(d.to_s).+(t.hour.to_s)") %x{...} forks an new process to run the command, and will not raise an exception if that program 'fails'. However you can check $? which is the status of the most recently terminated child. >> %x{flurble} (irb):4: command not found: flurble => "" >> $? => # >> $?.methods - Object.methods => ["success?", "exitstatus", "&", ">>", "stopped?", "stopsig", "to_i", "coredump?", "to_int", "signaled?", "termsig", "pid", "exited?"] >> $?.success? => false So you would write your code as: res = %x{...whatever...} unless $?.success? die_mtd "SQL_Dump_Cmd_Failed with status #{$?.exitstatus}" end Note that the stdout from the command is captured in 'res'. If you are not going to make use of this, it's probably better to do system "...whatever..." which will allow the child's stdout to go to your ruby script's stdout. -- Posted via http://www.ruby-forum.com/.