Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Capturing the Return Code from an External Program

    I have an ado file that calls an external binary executable. Is there any way to capture the return code? I got as far as:

    Code:
     ! (program <filein >fileout; echo $?)
    which (in Linux or OSX) echoes the return code in the log, but doesn't give the ado file access. A -capture- command usually sets _rc, but

    Code:
    capture ! program
    di _rc
    always returns a zero. Any thoughts? There are obvious workarounds, but if there is a "right" way, I'd like to do that.

  • #2
    If the error code is in a file, the file can be read by -file- or fileread(). Maybe using Stata + python is an option, then the python subprocess module can be used. A Windows cmd shell example, leaving a local macro with the error code from the cmd shell:
    Code:
    python:
    
    from sfi import Macro
    import subprocess
    
    pro = subprocess.run('cmd /c "nonexiting.bat"')
    
    Macro.setLocal("RC", str(pro.returncode) )
    
    end
    
    di "`RC'"

    Comment


    • #3
      Following #2, given a local RC:
      Code:
      capture assert ( `RC' == 0 )
      
      if ( _rc == 9 ) {
      
        di as err "process failed with cmd shell error code: " `RC'
        exit _rc
      }
      using #2 and the above in a small ado with sub programs:

      Code:
      prog def myprog
      
      display "before test_subprocess"
      
      test_subprocess // if error: display shell error code and exit with _rc 9 
      
      display "after test_subprocess"
               
      end
      
      * sub programs
      
      program define test_subprocess
      
      python: test_subprocess()
      
      capture assert ( `RC' == 0 )
      
      if ( _rc == 9 ) {
       
        di as err "process failed with cmd shell error code: " `RC'
        exit _rc
      }
         
      end
      
      python:
      
      def test_subprocess():
      
          from sfi import Macro
          import subprocess
      
          pro = subprocess.run('cmd /c "nonexiting.bat"')
      
          Macro.setLocal("RC", str(pro.returncode) )
         
      end
      Code:
      . myprog
      before test_subprocess
      process failed with cmd shell error code: 1
      r(9);

      Comment


      • #4
        Ref #2: If the error code is in a file, the file can be read by -file- or fileread(). Thus redirect to a tempfile should work. A Windows cmd shell example, redirect stderr to tempfile in myprog2.ado:
        Code:
        prog def myprog2
        
        display "before test_subprocess"
        
        test_subprocess `0' // if error: display shell error code and exit with _rc 9 
        
        display "after test_subprocess"
                 
        end
        
        * sub programs
        
        program define test_subprocess 
        
        tempfile stderr
        
        shell `0' 2> `stderr'   
        
        local errormessage = fileread("`stderr'") 
        
        capture assert "`errormessage'" == ""  
        
        if ( _rc == 9 ) {
            
            di as error "`errormessage'"     
            error _rc
        }
           
        end
        
        exit // test:  
        
        cls
        myprog2 dir
        myprog2 nonexisting.bat
        Code:
        . myprog2 dir
        before test_subprocess
        after test_subprocess
        
        . myprog2 nonexisting.bat
        before test_subprocess
        'nonexisting.bat' is not recognized as an internal or external command,
        operable program or batch file.
        
        r(9);

        Comment

        Working...
        X