2

In my batch file I've got the following code

SETLOCAL enabledelayedexpansion
7Z a -r ..\%ZIPNAME%.zip * >> uniqueid8.log
IF !ERRORLEVEL! GEQ 1 (
    CALL :getLineNumber errLine uniqueID8 -2
    PHP ..\..\shell_mailupdate.php ERROR !errLine! "7Z a -r ..\%ZIPNAME%.zip * >> ..\uniqueid8.log"
    ENDLOCAL & EXIT /B
)
ENDLOCAL

:getLineNumber is a function to get the line number:

:::::::::::::::::::::::::::::::::::::::::::::
:GetLineNumber <resultVar> <uniqueID> [LineOffset]
:: Detects the line number of the caller, the uniqueID have to be unique in the batch file
:: The lineno is return in the variable <resultVar> add with the [LineOffset]
SETLOCAL
for /F " usebackq tokens=1 delims=:" %%L IN (`findstr /N "%~2" "%~f0"`) DO set /a lineNr=%~3 + %%L
( 
  ENDLOCAL
  set "%~1=%LineNr%"
  goto :eof
)

Shell_mailupdate.php is php script which send me error information.

The batch file is called asynchronously from my web application using this function found on the exec page of php:

<?php
function execInBackground($path, $exe, $args = "") {
   global $conf;

   if (file_exists($path . $exe)) {
       chdir($path);
       if (substr(php_uname(), 0, 7) == "Windows"){
           pclose(popen("start \"bla\" \"" . $exe . "\" " . escapeshellarg($args), "r"));   
       } else {
           exec("./" . $exe . " " . escapeshellarg($args) . " > /dev/null &");   
       }
   }
}
?>

When the batch file is called (my server OS is Windows), I receive a mail telling me that the command didn't work and my batch is interrupted. And when I go to see the unique8.log, it is empty. But when I try this command directly (by replacing %ZIPNAME% by the name I want) on the server it works and create my zip file. There are also other call of the 7-zip command to extract data earlier on the script, but I suspect they didn't work too, as the data didn't get extracted. But I know the batch file runs smoothly when started manually.

It can't come from the variable, as I know from my mail that it was correctly intialized. I also have the last version of 7-zip installed.

EDIT: For those wondering why I do have such a configuration, I need to create big bundle out of many little bundle. This involved unpacking the little bundle and rearranging their content. As the operation is time consuming, I simply call this operation in the background and let my php script finish without waiting for the operation to finish, and it tells the end-user that a mail will be sent as soon as the operation is through.

EDIT2: After following Wimmel advice to write stderr in the log file, I got the following exception:

Der Befehl "7Z" ist entweder falsch geschrieben oder konnte nicht gefunden werden.

Which roughtly translate into

The command "7Z" is either written uncorrectly or couldn't be found

This is weird because, as I mentioned earlier, calling the batch script manually goes smoothly without such an exception.

Community
  • 1
  • 1
Eldros
  • 551
  • 1
  • 9
  • 28

2 Answers2

2

I have some suggestions you can try;

possibly the user running the script has not enough rights to write the file. You can first try to replace the line

7Z a -r ..\%ZIPNAME%.zip * >> uniqueid8.log

with

echo 7Z a -r ..\%ZIPNAME%.zip * >> uniqueid8.log

And look if it can write to uniqueid8.log, and there is a correct commandline. Next step is to see if the zipfile can be created:

echo test > ..\%ZIPNAME%.zip

If rights might be the problem, you can also temporary add IUSR and IWAM to the administrators group, just to verify if that changes anything. Also write stderr to the same logfile like this (also makes sure the logfile itself it not zipped):

7Z a -r ..\%ZIPNAME%.zip * >> ..\uniqueid8.log 2>&1

EDIT Regarding your error:

Der Befehl "7Z" ist entweder falsch geschrieben oder konnte nicht gefunden werden.

This probably means the directory containing 7z is in the path in your own user account, but not in the user account running the php script. The easiest way to solve this, is either entering the full path to 7z (you probably have to use c:\programme instead of c:\program files):

"c:\program files\7-zip\7Z" a -r ..\%ZIPNAME%.zip * >> uniqueid8.log

or add it to the path at the beginning of your batch file:

@echo off
set path="c:\program files\7-zip";%path%
wimh
  • 15,072
  • 6
  • 47
  • 98
  • I'm currently not at work for the following two weeks. It'll have to wait until then, to test your idea, but I can see it would make sense. – Eldros Aug 21 '11 at 15:46
  • the two echos did behave as one would expect, writing the information correctly in the log file or creating the zip file. Now I wanted to test giving administrator rights to the user you specified. However, I have a question: Is there any IUSR and IWAM users under Windows 2000? Because I don't seem to be able to find them. – Eldros Sep 05 '11 at 13:15
  • I edited my answer because of the EDIT2 in your original question. If you still need to know about the IUSR/IWAM on W2k, please let me know. I have to dig a bit for that.... ;) – wimh Sep 05 '11 at 16:37
  • Adding it to the path at the beginning did the trick, but wouldn't it clog the variable with repetition of the path? – Eldros Sep 06 '11 at 08:05
  • When you add it this way (`set path=...;%path%`) it will not be remembered for the next time. So it will only add it once. And even if is already in your path, for example when you run it under your own user account, it does not hurt if it is included twice. – wimh Sep 06 '11 at 09:04
0

I'd suspect the pclose is killing it off. There is a big difference between redirecting to /dev/null (which will accept any data and silently discard it) and closing it's standard output (which will cause any write to fail).

I think you should use exec also on Windows, just redirect to NUL instead of /dev/null

Also you should be redirecting both stdout and stderr on both platforms, so >NUL 2>NUL.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • Too bad, it looked promissing, but not only does it show the same behaviour, but now my php script is waiting for it's execution to stop. – Eldros Aug 19 '11 at 12:30
  • @Eldros: Try prefixing it with `start` command on windows. That's supposed to do something like `&` on unix. But I never tried it from php (nor run php on windows for that matter); just guessing. – Jan Hudec Aug 19 '11 at 12:43
  • If you look into `execInBackground` function, you'll see that it already use `start`. I didn't change that when I tried the solution you proposed. – Eldros Aug 19 '11 at 12:47
  • @Eldros: Hm, than I am out of ideas. – Jan Hudec Aug 19 '11 at 13:11