当前位置:首页> 正文

Linux下的.net应用问题,无法通过Shell脚本运行

Linux下的.net应用问题,无法通过Shell脚本运行

Problem with .net app under linux, doesn't work from shell script

我正在研究.net后提交钩子,以通过其Soap SDK将数据输入OnTime。我的钩子可以在Windows上正常工作,但是在我们的生产RHEL4颠覆服务器上,当从shell脚本中调用时,它将不起作用。

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

当我从命令行使用参数执行它时,它可以正常工作。通过shell脚本执行时,出现以下错误:(看来SVN的流程执行存在一些问题,我用来获取修订的日志数据):

1
2
3
4
5
6
7
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]

我尝试使用mkbundlemkbundle2制作一个可以命名为post-commit的独立文件,但是却收到了另一条错误消息:

1
2
3
4
5
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]

有任何想法为什么它可能会因Shell脚本而失败,或者捆绑版本可能有什么问题?

编辑:@赫姆斯,我已经用回声尝试过了,看起来不错。至于$1/hooks/post-commit.exe,我尝试了该脚本,无论是否具有指向.net程序集的完整路径,都具有相同的结果。

编辑:@Leon,我尝试了$1 $2"$@"的相同结果。它是一个Subversion提交后钩子,它具有两个参数,因此需要将其传递给.net程序集。 "$@"是在Mono站点上建议从外壳程序脚本调用.net程序集的内容。 Shell脚本正在执行.net程序集并使用正确的参数,但是会引发异常,当直接从命令行运行该脚本时不会引发该异常。

编辑:@Vinko,除了BASH_LINENOBASH_SOURCE之类的东西之外,我看不到其他任何环境差异

编辑:@卢克,我很累,但这也没有区别。我首先在机器上从TortoiseSVN进行测试时注意到了这个问题(当它作为Subversion守护程序的子进程运行时),但是还发现从hooks目录执行脚本(即./post-commit REPOS REV,其中post-commit是上面的sh脚本。做mono post-commit.exe REPOS REV很好用,主要的问题是要执行,我需要有一个名为post-commit的东西才能被调用。 Shell脚本,并且如上所述,mkbundle不能解决其他问题。


在关闭标准输出后,某些进程会挂起一段时间是正常的(即,您从它们中读取了文件结尾)。在读取所有数据之后但在检查ExitCode之前,需要调用proc.WaitForExit()


在验证我的代码在命令行中可以正常工作之后,我发现它不再有效!我调查了.net代码,看是否有意义。

这是我所拥有的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        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;
        }

我改变了这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
            while (!proc.HasExited)
            {
                sLine = proc.StandardOutput.ReadLine();
                if (sLine != null)
                {
                    ++nLine;
                    if (callback != null)
                    {
                        callback.Invoke(nLine, sLine);
                    }
                }
            }
            int errorCode = proc.ExitCode;

看起来Process的挂起时间比我得到输出的时间长,因此proc.ExitCode抛出错误。


尝试在运行单声道的行之前放置" cd $ 1 / hooks /"。您可能在该文件夹中有一些程序集,这些程序集是在外壳程序中从该文件夹运行mono时找到的,但在运行脚本时找不到。


比较您的外壳和脚本中的环境变量。


确定要做吗

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

$ @扩展为ALL参数。" $ @"扩展为所有由空格连接的参数。我怀疑您的Shell脚本不正确。您没有确切说明您希望脚本执行的操作,因此确实限制了我们提出建议的可能性。


只是一个随机想法,可能有助于调试。尝试将您的Shell脚本更改为:

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

检查并查看其打印的行是否与您期望它运行的命令匹配。 shell脚本中的命令行参数处理可能没有按照您想要的去做。

我不知道您对该脚本的预期输入是什么,但是路径之前的$ 1在我看来有点不合适。


展开全文阅读

相关内容