Я работаю над обработкой пост-фиксации .net для передачи данных в OnTime через их Soap SDK. Моя ловушка работает в Windows нормально, но на нашем производственном сервере подрывной деятельности RHEL4 она не будет работать при вызове из сценария оболочки.
#!/bin/sh /usr/bin/mono /hooks/post-commit.exe "$@"
Когда я выполняю его с параметрами из командной строки, он работает правильно. При выполнении через сценарий оболочки я получаю следующую ошибку: (похоже, есть проблема с выполнением процесса SVN, который я использую для получения данных журнала для ревизии):
Unhandled Exception: System.InvalidOperationException: The process must exit before getting the requested information. at System.Diagnostics.Process.get_ExitCode () [0x0003f] in /tmp/monobuild/build/BUILD/mono-1.9.1/mcs/class/System/System.Diagnostics/Process.cs:149 at (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ExitCode () at SVNLib.SVN.Execute (System.String sCMD, System.String sParams, System.String sComment, System.String sUserPwd, SVNLib.SVNCallback callback) [0x00000] at SVNLib.SVN.Log (System.String sUrl, Int32 nRevLow, Int32 nRevHigh, SVNLib.SVNCallback callback) [0x00000] at SVNLib.SVN.LogAsString (System.String sUrl, Int32 nRevLow, Int32 nRevHigh) [0x00000] at SVNCommit2OnTime.Program.Main (System.String[] args) [0x00000]
Я пробовал использовать mkbundle и mkbundle2 для создания автономной системы с именем post-commit, но получаю другое сообщение об ошибке:
Unhandled Exception: System.ArgumentNullException: Argument cannot be null. Parameter name: Value cannot be null. at System.Guid.CheckNull (System.Object o) [0x00000] at System.Guid..ctor (System.String g) [0x00000] at SVNCommit2OnTime.Program.Main (System.String[] args) [0x00000]
Есть идеи, почему он может не работать из сценария оболочки или что может быть не так с прилагаемой версией?
Редактировать:@Herms, с эхом уже пробовал, выглядит нормально. Что касается /hooks/post-commit.exe, я пробовал сценарий с полным путем к сборке .net и без него с теми же результатами.
Редактировать:@Леон, Я пробовал как , так и "$@" с одинаковыми результатами. Это хук фиксации пост-фиксации Subversion, и он принимает два параметра, поэтому их необходимо передать сборке .net. "$@" был тем, что рекомендовалось на моно-сайте для вызова сборки .net из сценария оболочки. Сценарий оболочки является выполняет сборку .net и с правильными параметрами, но генерирует исключение, которое не генерируется при запуске непосредственно из командной строки.
Редактировать:@Vinko, я не вижу отличий в окружении, кроме BASH_LINENO и BASH_SOURCE
Редактировать:@ Люк, надоело, но это тоже без разницы. Я впервые заметил проблему при тестировании из TortoiseSVN на моем компьютере (когда он работает как подпроцесс демона подрывной деятельности), но также обнаружил, что получаю те же результаты при выполнении сценария из каталога хуков (т.е. ./post-commit REPOS REV, где post-commit - это приведенный выше сценарий sh. Выполнение mono post-commit.exe REPOS REV работает нормально. Основная проблема заключается в том, что для выполнения мне нужно иметь что-то от имени post-commit, чтобы он был вызван. Но он не работает из сценария оболочки, и, как указано выше, mkbundle не работает с другой проблемой.





Просто случайная мысль, которая может помочь с отладкой. Попробуйте изменить сценарий оболочки на:
#!/bin/sh
echo /usr/bin/mono /hooks/post-commit.exe "$@"
Проверьте, соответствует ли выводимая строка команде, которую вы ожидаете запустить. Возможно, ваша обработка аргументов командной строки в сценарии оболочки не выполняет то, что вы хотите.
Я не знаю, каким должен быть ваш ввод в сценарий, но $ 1 перед путем мне кажется немного неуместным.
Вы уверены, что хотите сделать
/usr/bin/mono /hooks/post-commit.exe "$@"$ @ расширяется до ВСЕХ аргументов. «$ @» заменяется на все аргументы, соединенные пробелами. Я подозреваю, что ваш сценарий оболочки неверен. Вы не указали, что именно должен делать сценарий, так что это ограничивает наши возможности вносить предложения.
Сравните переменные среды в вашей оболочке и в сценарии.
Попробуйте поставить "cd $ 1 / hooks /" перед строкой, которая запускает моно. В этой папке могут быть сборки, которые обнаруживаются при запуске моно из этой папки в оболочке, но не обнаруживаются при запуске сценария.
Убедившись, что мой код сделал работает из командной строки, я обнаружил, что он больше не работает! Я заглянул в свой код .net, чтобы увидеть, есть ли что-нибудь в этом смысл.
Вот что у меня было:
static public int Execute(string sCMD, string sParams, string sComment,
string sUserPwd, SVNCallback callback)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Verb = "open";
proc.StartInfo.FileName = "svn";
proc.StartInfo.Arguments = Cmd(sCMD, sParams, sComment, UserPass());
proc.Start();
int nLine = 0;
string sLine = "";
while ((sLine = proc.StandardOutput.ReadLine()) != null)
{
++nLine;
if (callback != null)
{
callback.Invoke(nLine, sLine);
}
}
int errorCode = proc.ExitCode;
proc.Close();
return errorCode;
}
Я изменил это:
while (!proc.HasExited)
{
sLine = proc.StandardOutput.ReadLine();
if (sLine != null)
{
++nLine;
if (callback != null)
{
callback.Invoke(nLine, sLine);
}
}
}
int errorCode = proc.ExitCode;
Похоже, что процесс задерживается немного дольше, чем я получаю вывод, и поэтому proc.ExitCode выдает ошибку.
Некоторые процессы могут оставаться в стороне некоторое время после закрытия своего стандартного вывода (т. Е. Вы получаете от них сообщение о конце файла). Вам необходимо вызвать proc.WaitForExit() после прочтения всех данных, но до проверки ExitCode.