【问题标题】:Using SSH to run custom scripts on a Unix server in C#使用 SSH 在 C# 中的 Unix 服务器上运行自定义脚本
【发布时间】:2011-08-17 23:43:38
【问题描述】:

大家好,我一直在使用 new SHH library 向 unix 服务器发送命令,它对我来说非常有用。它可以很好地发送正常命令并接收正确的响应。但是,当我尝试使用它来运行自定义脚本(不是 shell 脚本,而是包含另一个命令并具有参数的文件)时,我似乎遇到了问题

我已经尝试了几种方法来让它发挥作用。

在 unix 服务器本身上,以下命令可以完美运行并按预期执行:

  • cd 脚本; script.oi someArg someArg - 工作
  • csh -c "cd script; script.oi someArg someArg" - 也可以使用
  • cd /users/bin/script; script.oi someArg1 someArg 2 - 工作
  • csh -c "cd /users/bin/script; script.oi someArg1 someArg 2" - 工作
  • /users/bin/script/script.oi someArg1 someArg2 - 工作

但是,在代码中我尝试了以下操作:

string command = string.Format("csh -c \"cd script; script.oi {0} {1}\"", arg1, arg2); - DOES NOT WORK
string command = string.Format("cd script; script.oi {0} {1}", arg1, arg2); - DOES NOT WORK
string command = string.Format("cd /users/bin/script; script.oi {0} {1}", arg1, arg2); - DOES NOT WORK 
string command = string.Format("csh -c \"cd /users/bin/script; script.oi {0} {1}\"", arg1, arg2); - DOES NOT WORK 
string command = string.Format("/users/bin/script/script.oi {0} {1}", arg1, arg2); - DOES NOT WORK

所以对我来说,似乎发生了其他事情。我确实尝试了以下方法:

string command = string.Format("csh -c \"ls\"", arg1, arg2);` - WORKS
string command = string.Format("ls", arg1, arg2);` - WORKS

这似乎与我尝试运行自定义脚本的事实有关,或者可能是我忘记了一些愚蠢的设置。如果您需要更多详细信息,请告诉我。

编辑: 不工作,我的意思是返回到 C# 的结果应该说一些东西,但结果是空白的。此外,该脚本发送一条 TIBCO Rendevous 消息,该消息最终将一个条目添加到未显示的数据库中。当我说 WORKS 时,我的意思是该条目显示在数据库中。

【问题讨论】:

  • 不工作是什么意思?您收到错误消息吗?你得到一个无效的结果吗?我只是想知道您是否可以在自定义脚本的情况下使用带空格或无效字符的参数?还有:script.oi 有什么模式? 777? 755?
  • 结果(命令的输出)是空白的,并且脚本应该通过发送 TIBCO Rendevous 消息将条目添加到 DB,并且永远不会添加该条目。不确定脚本模式是什么意思....只是带有参数的 TIBCO Rendevous 消息
  • 只是script.oi 的文件系统的权限。 ls -al /users/bin/script/script.oi 输出什么?
  • 我是一个巨大的 unix 菜鸟,但是当我运行该命令时,我认为您正在寻找的是它的开头-rwx--x--x
  • 另外,arg1arg2 的值是多少?您使用哪个用户登录?

标签: c# unix .net-4.0 ssh


【解决方案1】:

使用 ssh 客户端登录的用户是否对调用的可执行文件具有执行权限?

【讨论】:

  • 运行这些可执行文件/脚本时在实际 Unix 服务器上登录的用户与我在 SSH 连接上用于登录信息的用户/密码相同
  • 尝试使用不同的 shell 运行它们?例如 Bash?
  • 另外返回 pwd 也是值得的,它可以让你看到你的执行将在哪个目录中发生......
  • 实际上更好的是,像这样通过管道输出命令的输出:script.oi a2test003 hed > output.txt
  • 先尝试运行“touch output.txt”。应该创建文件。
【解决方案2】:

由于脚本应该是每个人都可以执行的,所以参数应该有问题。获取生成的命令字符串并尝试在 SSH 会话(使用 PuTTY 之类的东西)上自己执行它。如果可能,请向我们提供生成的命令。我认为其中可能有需要适当转义的字符。

【讨论】:

  • 即使参数只是字符串,<> 这样的空格和字符也可能会产生问题。
  • 啊,我明白了,电流类似于script.oi A2TEST003 HED
  • 好的,这应该不是问题。您可以使用 PuTTY (chiark.greenend.org.uk/~sgtatham/putty) 之类的 SSH 客户端登录并通过键入命令执行命令吗?
  • 好的,通过 PuTTY 使用相同的信息连接并运行 cd script; script.oi A2TEST003 HED 并且该条目确实出现在数据库中
【解决方案3】:

好吧,我想通了。原来脚本正在运行一个命令,该命令通过添加到 unix 环境变量中为 unix 服务器所知。仅使用标准方式在 SSH.NET 中发送命令时,不会导入环境变量(这就是为什么您可以发送 ls、grep、cat 等普通命令,但不能发送此命令的原因)。

修复是使用库 SSH shell 功能,因为它确实导入环境变量,因此它知道脚本中的命令是什么并且能够运行它。对于那些使用这个很棒的库(它仍在积极开发中,总是一个优点)的人,我在下面包含了示例 SSH.NET Shell 代码。

PasswordConnectionInfo connectionInfo = new PasswordConnectionInfo("some IP", "user", "pass");

try
{
    using (var client = new SshClient(connectionInfo))
    {
        client.Connect();
        var input = new MemoryStream(Encoding.ASCII.GetBytes(command));
        var shell = client.CreateShell(input, Console.Out, Console.Out, "xterm", 80, 24, 800, 600, "");
        shell.Stopped += delegate(object sender, EventArgs e)
        {
            Console.WriteLine("\nDisconnected...");
        };
        shell.Start();
        Thread.Sleep(1000);
        shell.Stop();
        client.Disconnect();
    }   
}
catch (Exception ex)
{
    // Exception stuff
}

【讨论】:

    猜你喜欢
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2018-09-21
    相关资源
    最近更新 更多