Linux에서 .net 앱 문제가 발생하고 쉘 스크립트에서 작동하지 않습니다.
문제
저는 Soap SDK를 통해 OnTime에 데이터를 공급하기 위해 .net 커밋 후 후크를 작업 중입니다.내 후크는 Windows에서는 잘 작동하지만 프로덕션 RHEL4 Subversion 서버에서는 쉘 스크립트에서 호출할 때 작동하지 않습니다.
#!/bin/sh /usr/bin/mono $1/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]
쉘 스크립트에서 실패하는 이유나 번들 버전에 어떤 문제가 있을 수 있는지 아시나요?
편집하다: @헴스, 이미 에코로 시도해 봤는데 맞는 것 같습니다.에 관해서는 $1/hooks/post-commit.exe
, .net 어셈블리에 대한 전체 경로가 있거나 없는 스크립트를 시도했지만 동일한 결과가 나왔습니다.
편집하다: @레온, 둘 다 시도해 봤어요 $1 $2
그리고 "$@"
같은 결과로.이는 전복 후 커밋 후크이며 두 개의 매개 변수를 사용하므로 해당 매개 변수를 .net 어셈블리에 전달해야 합니다.그만큼 "$@"
이는 쉘 스크립트에서 .net 어셈블리를 호출하기 위해 모노 사이트에서 권장된 것입니다.쉘 스크립트 ~이다 올바른 매개변수를 사용하여 .net 어셈블리를 실행하지만 명령줄에서 직접 실행할 때 발생하지 않는 예외가 발생합니다.
편집하다: @빈코, 나는 다음과 같은 것 외에는 환경에 어떤 차이도 보이지 않습니다. BASH_LINENO
그리고 BASH_SOURCE
편집하다: @루크, 피곤했지만 그것도 아무런 차이가 없습니다.내 컴퓨터의 TortoiseSVN에서 테스트할 때(Subversion 데몬의 하위 프로세스로 실행될 때) 처음으로 문제를 발견했지만 후크 디렉터리(예: ./post-commit REPOS REV
, 어디 post-commit
위의 sh 스크립트입니다.행위 mono post-commit.exe REPOS REV
잘 작동합니다.가장 큰 문제는 실행하려면 이름이 필요하다는 것입니다. post-commit
그래서 그것은 호출됩니다.그러나 이는 쉘 스크립트에서는 작동하지 않으며 위에서 언급한 것처럼 mkbundle
다른 문제로 작업하지 않습니다.
해결책
일부 프로세스가 stdout을 닫은 후 잠시 동안 머무르는 것은 정상입니다(예:당신은 그들로부터 파일 끝을 읽습니다).전화를 하셔야 해요 proc.WaitForExit()
모든 데이터를 읽은 후 ExitCode를 확인하기 전에.
다른 팁
디버깅에 도움이 될 수 있는 무작위적인 생각입니다.쉘 스크립트를 다음과 같이 변경해 보십시오.
#!/bin/sh
echo /usr/bin/mono $1/hooks/post-commit.exe "$@"
인쇄되는 줄이 실행하려는 명령과 일치하는지 확인하세요.쉘 스크립트의 명령줄 인수 처리가 원하는 작업을 수행하지 않을 수도 있습니다.
스크립트에 대한 입력이 무엇일 것으로 예상되는지는 모르겠지만 경로 앞의 $1이 제 눈에는 약간 이상해 보입니다.
정말 하고 싶으신가요?
/usr/bin/mono $1/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
오류가 발생하고 있습니다.