Команда 7-Zip не выполняется, когда в асинхронно вызванном пакете из php - PullRequest
2 голосов
/ 19 августа 2011

В моем пакетном файле у меня есть следующий код

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 - это функция для получения номера строки :

:::::::::::::::::::::::::::::::::::::::::::::
: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 - это php-скрипт, который отправляет мне информацию об ошибке.

Пакетный файл вызывается асинхронно из моего веб-приложения, используя эту функцию, найденную на странице exec 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 &");   
       }
   }
}
?>

Когда вызывается пакетный файл (моя серверная ОС - Windows), я получаю письмо, в котором сообщается, что команда не работает и мой пакет прерывается.И когда я иду, чтобы увидеть unique8.log, он пуст.Но когда я пробую эту команду напрямую (заменив% ZIPNAME% на имя, которое я хочу) на сервере, она работает и создает мой zip-файл.Есть также другой вызов команды 7-zip для извлечения данных ранее в сценарии, но я подозреваю, что они тоже не сработали, так как данные не были извлечены.Но я знаю, что пакетный файл работает без проблем при запуске вручную.

Он не может быть получен из переменной, поскольку я знаю из своей почты, что он был правильно инициализирован.У меня также установлена ​​последняя версия 7-zip.

РЕДАКТИРОВАТЬ: Для тех, кто задается вопросом, почему у меня такая конфигурация, мне нужно создать большой комплект из множества маленьких комплектов.Это включало распаковку небольшого пакета и перестановку их содержимого.Поскольку операция занимает много времени, я просто вызываю эту операцию в фоновом режиме и позволяю моему php-скрипту завершиться, не дожидаясь завершения операции, и он сообщает конечному пользователю, что письмо будет отправлено, как только операция завершится.

EDIT2: После того, как Wimmel советовал записать stderr в файл журнала, я получил следующее исключение:

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

Что примерно переводится в

Команда "7Z" либо написана неправильно, либо не найдена

Это странно, потому что, как я упоминал ранее, вызов пакетного скрипта вручную проходит без каких-либо исключений.

Ответы [ 2 ]

2 голосов
/ 19 августа 2011

У меня есть несколько предложений, которые вы можете попробовать;

возможно, у пользователя, выполняющего скрипт, недостаточно прав для записи файла. Вы можете сначала попробовать заменить строку

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

с

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

И посмотрите, может ли он писать в uniqueid8.log, и есть ли правильная командная строка. Следующим шагом является проверка возможности создания zip-файла:

echo test > ..\%ZIPNAME%.zip

Если права могут быть проблемой, вы также можете временно добавить IUSR и IWAM в группу администраторов, просто чтобы убедиться, что это что-то меняет. Также напишите stderr в тот же файл журнала, как этот (также убедитесь, что сам файл журнала не заархивирован):

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

EDIT По поводу вашей ошибки:

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

Это, вероятно, означает, что каталог, содержащий 7z, находится в пути в вашей собственной учетной записи пользователя, но не в учетной записи пользователя, выполняющей скрипт php. Самый простой способ решить эту проблему - ввести полный путь к 7z (вам, вероятно, придется использовать c:\programme вместо c:\program files):

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

или добавьте его в путь в начале вашего командного файла:

@echo off
set path="c:\program files\7-zip";%path%
0 голосов
/ 19 августа 2011

Я подозреваю, что pclose убивает его. Существует большая разница между перенаправлением на /dev/null (которое будет принимать любые данные и молча отбрасывать его) и закрытием стандартного вывода (что приведет к сбою любой записи).

Я думаю, вы должны использовать exec также в Windows, просто перенаправить на NUL вместо /dev/null

Также вы должны перенаправить как stdout, так и stderr на обе платформы, поэтому >NUL 2>NUL.

...