views:

322

answers:

4

I'm writing a quick Rails app and was wondering how I can validate the success an exec'd command. The two commands I'm running are and SVN update, and a cp from one directory to another.

A: 

For SVN update, check the version number before and after the update.

svn_start_version = IO.popen("svn info").readlines[4]
`svn update`
svn_end_version = IO.popen("svn info").readlines[4]
if svn_end_version > svn_start_version
  "success"
end

For the cp, you could do a filesize check on the original file being equal to the copied file.

source_file_size = IO.popen("du file1").readlines
`cp file1 file2`
dest_file_size = IO.popen("du file2").readlines
if dest_file_size == source_file_size
  "success"
end
Unixmonkey
What if the subversion repository was not changed? Your code would indicate failure. What if the file contents had changed but not the number of allocated blocks (and the copy operation failed)? Your code would indicate success.
Greg Hewgill
+1  A: 

How are you executing the external commands? The Ruby system() function returns true or false depending on whether the command was successful. Additionally, $? contains an error status.

Greg Hewgill
+7  A: 

If you use the Kernel.system() method it will return a boolean indicating the success of the command.

result = system("cp -r dir1 dir2")
if(result)
#do the next thing
else
# handle the error

There is a good comparison of different ruby system commands here.

Gordon Wilson
+1  A: 
  1. Just to be pedantic, you can't validate an exec'd command because exec replaces the current program with the exec'd command, so the command would never return to Ruby for validation.
  2. For the cp, at least, you would probably be better of using the FileUtils module (part of the Ruby Standard Library), rather than dropping to the shell.
  3. As noted above, the $? predefined variable will give you the return code of the last command to be executed by system() or the backtick operator.
Avdi
Yeah, exec really threw me when I first started ruby programming. Basically, don't use it!
Orion Edwards