Problema con la aplicación .net en Linux, no funciona desde script de shell

Estoy trabajando en un enlace .net post-commit para alimentar datos en OnTime a través de su SOAP SDK. Mi gancho funciona bien en Windows, pero en nuestro server de subversión RHEL4 de producción, no funcionará cuando se llame desde un script de shell.

 #! / bin / sh
 / usr / bin / mono $ 1 / hooks / post-commit.exe "$ @"

Cuando lo ejecuto con parameters de la línea de command, funciona correctamente. Cuando se ejecuta mediante el script de shell, aparece el siguiente error: (parece que hay algún problema con la ejecución del process de SVN que utilizo para get los datos de logging para la revisión):


 Excepción no controlada: System.InvalidOperationException: el process debe salir antes de get la información solicitada.
   en System.Diagnostics.Process.get_ExitCode () [0x0003f] en /tmp/monobuild/build/BUILD/mono-1.9.1/mcs/class/System/System.Diagnostics/Process.cs:149
   at (contenedor remoto-invocar-con-verificar) System.Diagnostics.Process: get_ExitCode ()
   en SVNLib.SVN.Execute (System.String sCMD, System.String sParams, System.String sComment, System.String sUserPwd, SVNLib.SVNCallback callback) [0x00000]
   en SVNLib.SVN.Log (System.String sUrl, Int32 nRevLow, Int32 nRevHigh, SVNLib.SVNCallback de callback) [0x00000]
   en SVNLib.SVN.LogAsString (System.String sUrl, Int32 nRevLow, Int32 nRevHigh) [0x00000]
   en SVNCommit2OnTime.Program.Main (System.String [] args) [0x00000]

Intenté usar mkbundle y mkbundle2 para hacer una mkbundle2 independiente que podría llamarse post-commit , pero recibo un post de error diferente:

 Excepción no controlada: System.ArgumentNullException: Argument no puede ser nulo.
 Nombre del parámetro: el valor no puede ser nulo.
   en System.Guid.CheckNull (System.Object o) [0x00000]
   en System.Guid..ctor (System.String g) [0x00000]
   en SVNCommit2OnTime.Program.Main (System.String [] args) [0x00000]

¿Alguna idea de por qué podría fallar en un script de shell o qué podría estar mal con la versión incluida?

Edit: @Herms , ya lo probé con un eco, y se ve bien. En cuanto al $1/hooks/post-commit.exe , probé el script con y sin una ruta completa al ensamblado .net con los mismos resultados.

Editar: @Leon , probé $1 $2 y "$@" con los mismos resultados. Es un enlace de confirmación posterior a la postulación, y toma dos parameters, por lo que deben pasarse al ensamblado .net. El "$@" era lo que se recomendaba en el sitio mono para llamar a un ensamblado .net desde un script de shell. El script de shell está ejecutando el ensamblado .net y con los parameters correctos, pero arroja una exception que no se lanza cuando se ejecuta directamente desde la línea de command.

Editar: @Vinko , no veo diferencias en el entorno que no sean cosas como BASH_LINENO y BASH_SOURCE

Editar: @Luke , lo cansé, pero eso tampoco importa . La primera vez que noté el problema fue al probar desde TortoiseSVN en mi máquina (cuando se ejecuta como un subprocess del daemon de subversión), pero también descubrí que obtengo los mismos resultados cuando ejecuto el script desde el directory hooks (es decir, ./post-commit REPOS REV , donde post-commit es el script sh anterior. Hacer mono post-commit.exe REPOS REV funciona bien. El problema principal es que para ejecutar, necesito tener algo del nombre post-commit para que sea llamado. Pero no funciona desde un script de shell, y como se señaló anteriormente, el mkbundle no funciona con un problema diferente.

Es normal que algunos processs se queden por un time después de cerrar su stdout (es decir, usted obtiene una lectura de final de file de ellos). proc.WaitForExit() llamar a proc.WaitForExit() después de leer todos los datos pero antes de verificar ExitCode.

Solo un pensamiento random que podría ayudar con la debugging. Intenta cambiar tu script de shell por:

 #!/bin/sh echo /usr/bin/mono $1/hooks/post-commit.exe "$@" 

Compruebe y vea si la línea que imprime coincide con el command que espera que se ejecute. Es posible que el event handling los arguments de command-line en el script de shell no esté haciendo lo que usted quiere que haga.

No sé qué se espera que sea tu input al script, pero el $ 1 antes de que el path parezca un poco fuera de lugar para mí.

¿Estás seguro de que quieres hacer

 /usr/bin/mono $1/hooks/post-commit.exe "$@" 

$ @ se expande a TODOS los arguments. "$ @" se expande a todos los arguments que se unen por espacios. Sospecho que tu script de shell es incorrecto. No indicó exactamente lo que quería que hiciera el script, por lo que limita nuestras posibilidades de hacer sugerencias.

Compare las variables de entorno en su shell y desde dentro del script.

Intenta poner "cd $ 1 / hooks /" antes de la línea que se ejecuta en mono. Puede tener algunos ensambles en esa carpeta que se encuentran cuando ejecuta mono desde esa carpeta en el shell pero no se encuentran cuando ejecuta el script.

Después de haber verificado que mi código funcionaba desde la command-line, ¡descubrí que ya no funcionaba! Fui a search en mi código .net para ver si algo tenía sentido.

Esto es lo que tuve:

         static public int Execute (string sCMD, string sParams, string sComment,
                                   string sUserPwd, callback SVNCallback)
         {
             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 = "abrir";
             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;
         }

Cambié esto:

             while (! proc.HasExited)
             {
                 sLine = proc.StandardOutput.ReadLine ();
                 if (sLine! = null)
                 {
                     ++ nLine;
                     if (callback! = null)
                     {
                         callback.Invoke (nLine, sLine);
                     }
                 }
             }
             int errorCode = proc.ExitCode;

Parece que el process se demora un poco más de lo que estoy obteniendo resultados, y por lo tanto el proc.ExitCode está arrojando un error.