title: Retrieve %ERRORLEVEL% with complicated call in FOR loop
body: <p>In a Windows batch file I needed to retrieve the result of a program execution into a variable, when the program call was complicated with spaces and several options. After much discussion, a workaround was found by using <code>CALL</code>:</p>
  
  <pre><code>FOR /F "delims=" %%G IN ('CALL "C:\path with spaces\foo.bat" "blah blah='foobar' blah"') do set foo=%%G
  </code></pre>
  
  <p>Please see the following question for more details and to understand the context:</p>
  
  <p><a href="https://stackoverflow.com/q/33370883/421049">Retrieve command output to variable when command has spaces</a></p>
  
  <p>In reality the batch file calls PostgreSQL 9.3, like this:</p>
  
  <pre><code>SET PSQL_EXE=C:\Program Files\Foo\Bar\PostgreSQL\9.3\bin\psql.exe
  SET FOO=1
  REM psql query should result in a 0 or 1 based on the mydbproperty table value
  FOR /F %%G IN ('call "%PSQL_EXE%" -U pguser -d MyDB -p %PG_PORT% -c "select string_value from mydb.uri as uri, mydb.property as prop where uri.id = prop.property_uriid and uri.namespace_uri='http://example.com/foo/bar/' and uri.simplename = 'fooBar'" -q -t -w') DO SET FOO=%%G
  REM next line doesn't have ERRORLEVEL set
  IF !ERRORLEVEL! NEQ 0 EXIT !ERRORLEVEL!
  </code></pre>
  
  <p>Unfortunately it appears that this format results in a separate <code>cmd</code> instance, so any error that occurred in calling pgsql (e.g. the lack of a password file) does not get passed back and the <code>%ERRORLEVEL%</code> does not get set. Specifically pgsql prints out:</p>
  
  <pre><code>psql: fe_sendauth: no password supplied
  </code></pre>
  
  <p>Yet <code>%ERRORLEVEL%</code> (and <code>!ERRORLEVEL!</code>) is still <code>0</code>.</p>
  
  <p>See the following question for more info:</p>
  
  <p><a href="https://stackoverflow.com/q/30767449/421049">PSQL Error Level in Batch For Loop</a></p>
  
  <p>So now the question is how to find out the %ERRORLEVEL%, now that I've succeeding in getting the response of <code>psql</code>. I'd prefer not to write to some temporary file---I want to do everything in memory.</p>
  
  <p>(Note that, yes, the value I'm trying to query from the database and store in <code>FOO</code> will be either a <code>0</code> or a <code>1</code>; not that it matters, but it does make things more confusing.)</p>
  
  <p>I tried to test Aacini's proposed solution by simply seeing what would be returned in <code>%%G</code>:</p>
  
  <pre><code>FOR /F "delims=" %%G IN ('"CMD /V:ON /C CALL "%PSQL_EXE%" -U user -d MyDB -p %PG_PORT% -c "select string_value from mydb.uri as uri, mydb.database_property as prop where uri.id = prop.property_uriid and uri.namespace_uri='http://example.com/foo/bar/' and uri.simplename = 'fooBar'" -q -t -w ^&amp; ECHO !ERRORLEVEL!"') DO (
    ECHO %%G
  )
  </code></pre>
  
  <p>Because psql could not find a password file, this prints an error to stderr (as expected) and the <code>ECHO</code> outputs <code>0</code>---so the <code>ERRORLEVEL</code> is not getting sent back to the <code>DO</code> clause. But if I split out the command from the <code>FOR</code> loop and just run it directly, it shows the <code>ERRORLEVEL</code> (<code>2</code>) just fine!</p>
  
  <pre><code>"%PSQL_EXE%" -U user -d MyDB -p %PG_PORT% -c "select string_value from mydb.uri as uri, mydb.database_property as prop where uri.id = prop.property_uriid and uri.namespace_uri='http://example.com/foo/bar/' and uri.simplename = 'fooBar'" -q -t -w
  ECHO !ERRORLEVEL!
  </code></pre>
  
  <p>Update: After being advised that I need to escape the escapes if I have delayed expansion already turned on, I took the given answer and updated it to take into account that the program I'm calling won't return a value if it generates an error. So here's what I do; first I make sure two variables are undefined:</p>
  
  <pre><code>SET "var1="
  SET "var2="
  </code></pre>
  
  <p>Then I use the loop that @Aacini and @jeb gave, but inside the loop I do this:</p>
  
  <pre><code>if NOT DEFINED var1 (
    SET "var1=%%G"
  ) else (
    SET "var2=%%G"
  )
  </code></pre>
  
  <p>Then outside the loop after it has finished:</p>
  
  <pre><code>if DEFINED var2 (
    ECHO received value: !var1!
    ECHO ERRORLEVEL: !var2!
  ) ELSE (
    ECHO ERRORLEVEL: !var1!
  )
  </code></pre>
  
  <p>That seems to work. (Unbelievably---what gymnastics!)</p>