在 C# 中使用 SSH.NET CreateCommand 执行时,命令失败并显示“<command> 未找到”

Commands fail with “<command> not found”, when executed using SSH.NET CreateCommand in C#

我正在尝试使用 SSH.NET NuGet package 远程执行命令以获取安装在连接到 Mac 的 iPhone 上的应用程序版本。

如果使用以下命令在 Mac 本身上执行,将得到它的版本:

ideviceinstaller -l|grep <bundleIdOfMyAppPackage>

所以我用这个包在 C# 中构建了一个小实用程序,希望我能利用它。但是,我得到的只是一个空字符串。谁能让我知道我可以做些什么来获得我想要的结果?谢谢!

var host = "myhost";
var username = "username";
var password = "password";

using (var client = new SshClient(host, username, password))
{
    client.HostKeyReceived += delegate(object sender, HostKeyEventArgs e) { e.CanTrust = true; };

    client.Connect();
    var command = client.CreateCommand("ideviceinstaller -l|grep <bundleIdOfMyAppPackage>");
    command.Execute();

    var result = command.Result;
    Console.WriteLine(result);

    client.Disconnect();
}

我从 command.Error 得到的错误是

zsh1: command not found ideviceinstaller`

这很奇怪,因为如果我浏览到该文件夹​​,我可以在该文件夹中看到 ideviceinstaller


感谢@Martin Prikryl,我将命令更改为:

/usr/local/bin/ideviceinstaller -l|grep <myAppBundleId>

SSH.NETSshClient.CreateCommand(或SshClient.RunCommand)不会运行shell处于“登录”模式,也不会为session。因此,与您的常规交互式 SSH session. And/or 根据 absence/presence 的 TERM 环境变量,采用脚本中的不同分支。

可能的解决方案(按优先顺序):

  1. 修复命令不依赖于特定环境。在命令中使用 ideviceinstaller 的完整路径。例如:

     /path/to/ideviceinstaller ...
    

    如果您不知道完整路径,在常见的 *nix 系统上,您可以在交互式 SSH session.

    中使用 which ideviceinstaller 命令
  2. 修复您的启动脚本,将 PATH 设置为与 non-interactive sessions 相同。

  3. 尝试 运行 通过登录 shell 显式启用脚本(将 --login 开关与通用 *nix shells 一起使用):

     bash --login -c "ideviceinstaller ..."
    
  4. 如果命令本身依赖于特定的环境设置并且您无法修复启动脚本,则可以在命令本身中更改环境。那取决于远程系统的语法 and/or shell。在常见的 *nix 系统中,这有效:

     PATH="$PATH;/path/to/ideviceinstaller" && ideviceinstaller ...
    
  5. 另一个(不推荐)是使用“shell”通道通过SshClient.CreateShellStreamSshClient.CreateShell执行命令,因为这些分配伪终端

     ShellStream shellStream = client.CreateShellStream(string.Empty, 0, 0, 0, 0, 0);
     shellStream.Write("ideviceinstaller\n");
    
     while (true)
     {
         string s = shellStream.Read();
         Console.Write(s);
     }
    

    使用 shell 和伪终端自动执行命令会给您带来严重的副作用。