5 Replies Latest reply on Mar 8, 2019 3:20 PM by vbranden

    Stderr in external command execution seems to get lost

    schistad Enthusiast

      After some initial puzzlement I've discovered that when you run external programs, only file stream 1 (STDOUT) is captured in the command.output method. Unfortunately, there is no error handle and redirection does not seem to work either (eg command -parm arg1 2>&1).

       

      Do I need to write bash wrappers to redirect stderr, or is there a way to retrieve it from the result object?

        • 1. Re: Stderr in external command execution seems to get lost
          cdecanini_ Virtuoso
          VMware Employees

          This should work:

           

          scriptArguments = "/s /c cmd >" + scriptOutputFile + " 2>&1 /s /c " + script;
          
          • 2. Re: Stderr in external command execution seems to get lost
            igaydajiev Expert
            VMware Employees

            In case you are running cmd.exe you can do someting like this :

             

            cmd = new Command("cmd.exe /c dir NON_EXISTING_FOLDER 2>&1");

            cmd.execute(true);

            System.log(cmd.output)

            • 3. Re: Stderr in external command execution seems to get lost
              schistad Enthusiast

              This is on linux (the vCO Appliance), and I ended up doing pretty much this; I wrote a wrapper which invokes bash and runs $@ 2>&1.

              Eg:

               

               

              #!/bin/bash

              CMD=$1

              shift

              ARG=$@

              $CMD $ARG 2>&1

              • 4. Re: Stderr in external command execution seems to get lost
                cdecanini_ Virtuoso
                VMware Employees

                Sorry my answer was for running a Windows command in a guest using vCenter guest operations workflows.

                • 5. Re: Stderr in external command execution seems to get lost
                  vbranden Novice

                  I got around this by writing the command text to a temp file and executing it with stdout/stderr redirection to temp files for stdout and stderr then cleaning up the files at the end. Here is my action that takes a single parameter "command". this is working on embedded vRO in vRA 7.5

                   

                  // script file
                  var scriptFile = System.createTempFile(".sh")
                  scriptFile.createFile()
                  var scriptFilePath = scriptFile.path
                  
                  // stderr file
                  var stdErrFile = System.createTempFile()
                  stdErrFile.createFile()
                  var stdErrFilePath = stdErrFile.path
                  
                  // stdout file
                  var stdOutFile = System.createTempFile()
                  stdOutFile.createFile()
                  var stdOutFilePath = stdOutFile.path
                  
                  // build and execute command by creating and executing a script
                  var scriptText = "#!/bin/bash\n\n" + command + " 2> " + stdErrFilePath + " 1> " + stdOutFilePath
                  
                  var scriptFr = new FileWriter(scriptFilePath)
                  scriptFr.open()
                  scriptFr.write(scriptText)
                  scriptFr.close()
                  
                  var chmodCmd = new Command("chmod +x " + scriptFilePath)
                  chmodCmd.execute(true)
                  
                  var cmd = new Command(scriptFilePath)
                  cmd.execute(true)
                  
                  // get the output
                  var result = {
                    exitCode: cmd.result
                  }
                  
                  scriptFile.deleteFile()
                  
                  var errFr = new FileReader(stdErrFilePath)
                  errFr.open()
                  result.stderr = errFr.readAll().trim().replace(/\r/g, "")
                  stdErrFile.deleteFile()
                  
                  var outFr = new FileReader(stdOutFilePath)
                  outFr.open()
                  result.stdout = outFr.readAll().trim().replace(/\r/g, "")
                  stdOutFile.deleteFile()
                  
                  return result