Domanda

Sto lavorando su un .netto post-commit gancio per inserire dati nel OnTime tramite il loro Sapone SDK.Il mio gancio funziona su Windows bene, ma sulla nostra produzione RHEL4 server subversion, non funziona quando viene chiamato da uno script di shell.

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

Quando provo a eseguire con i parametri da riga di comando funziona correttamente.Quando viene eseguito tramite lo script di shell, ottengo il seguente errore:(sembra che ci sia qualche problema con il processo di esecuzione di SVN che uso per ottenere i dati di log per la revisione):

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]

Ho provato con mkbundle e mkbundle2 per fare un stand alone che potrebbero essere chiamati post-commit, ma ottengo un messaggio di errore diverso:

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]

Tutte le idee perché potrebbe essere mancata da uno script di shell o che cosa potrebbe essere sbagliato con la versione in bundle?

Edit: @Hermés, Ho già provato con un'eco, e si presenta bene.Come per il $1/hooks/post-commit.exe, Ho provato lo script con e senza un percorso completo .net assembly con gli stessi risultati.

Edit: @Leon, Ho provato sia $1 $2 e "$@" con gli stessi risultati.Si tratta di una sovversione post commettere gancio, e accetta due parametri, in modo che coloro che devono essere passati alla .net assembly.Il "$@" è ciò che è stato raccomandato al mono del sito per chiamare una .net assembly da uno script di shell.Lo script di shell è l'esecuzione del .net assembly e con i parametri corretti, ma è la generazione di un'eccezione che non viene generata quando viene eseguito direttamente dalla riga di comando.

Edit: @Vinko, Non vedo differenze nell'ambiente diverso da cose come BASH_LINENO e BASH_SOURCE

Edit: @Luca, Mi stanco di esso, ma che non fa alcuna differenza.Ho notato il problema durante il test da TortoiseSVN sulla mia macchina (quando viene eseguito come un sub-processo di sovversione demone), ma anche scoperto che ho ottenuto gli stessi risultati quando si esegue lo script da ganci directory (es. ./post-commit REPOS REV, dove post-commit è la sopra sh script.Facendo mono post-commit.exe REPOS REV funziona bene.Il problema principale è che per eseguire, ho bisogno di avere qualcosa di questo nome post-commit in modo che possa essere chiamato.Ma non da uno script di shell, e come notato in precedenza, il mkbundle non funziona con un problema diverso.

È stato utile?

Soluzione

E 'normale che alcuni processi di rimanere in giro per un po' dopo chiudono la loro stdout (ie.si ottiene un fine-di-lettura di file da loro).È necessario chiamare proc.WaitForExit() dopo la lettura di tutti i dati, ma prima di controllare ExitCode.

Altri suggerimenti

Solo un pensiero casuale che può aiutare con il debug.Prova a cambiare il tuo script di shell per:

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

Controllare e vedere se la linea di stampa corrisponda al comando che sei in attesa di esecuzione.È possibile che il tuo argomento della riga di comando la gestione di script di shell non è fare ciò che si vuole fare.

Non so che cosa il vostro input allo script dovrebbe essere, ma il $1, il sentiero sembra un po ' fuori luogo per me.

Sei sicuro di voler fare

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

$@ espande a TUTTI gli argomenti."$@" si espande a tutti gli argomenti di join da spazi.Ho il sospetto che la shell script non è corretto.Non stato esattamente ciò che si voleva lo script per fare in modo che limita le nostre possibilità di formulare proposte.

Confrontare le variabili di ambiente nel proprio guscio e dall'interno dello script.

Prova a mettere "cd $1/ganci/", prima che la linea che corre mono.Si può avere qualche assembly nella cartella che si trova quando si esegue mono da una cartella in the shell, ma non viene rilevato quando si esegue lo script.

Dopo aver verificato che il mio codice fatto lavorare da riga di comando, ho scoperto che non era più funzionante!Sono andato alla ricerca nel mio .net codice per vedere se qualcosa ha un senso.

Qui è quello che ho avuto:

        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;
        }

Ho cambiato questo:

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

Sembra che il Processo è in giro un po ' di più di quanto io sono sempre uscita, e quindi la proc.ExitCode è il lancio di un errore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top