在 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
环境变量,采用脚本中的不同分支。
可能的解决方案(按优先顺序):
修复命令不依赖于特定环境。在命令中使用 ideviceinstaller
的完整路径。例如:
/path/to/ideviceinstaller ...
如果您不知道完整路径,在常见的 *nix 系统上,您可以在交互式 SSH session.
中使用 which ideviceinstaller
命令
修复您的启动脚本,将 PATH
设置为与 non-interactive sessions 相同。
尝试 运行 通过登录 shell 显式启用脚本(将 --login
开关与通用 *nix shells 一起使用):
bash --login -c "ideviceinstaller ..."
如果命令本身依赖于特定的环境设置并且您无法修复启动脚本,则可以在命令本身中更改环境。那取决于远程系统的语法 and/or shell。在常见的 *nix 系统中,这有效:
PATH="$PATH;/path/to/ideviceinstaller" && ideviceinstaller ...
另一个(不推荐)是使用“shell”通道通过SshClient.CreateShellStream
或SshClient.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 和伪终端自动执行命令会给您带来严重的副作用。
我正在尝试使用 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
环境变量,采用脚本中的不同分支。
可能的解决方案(按优先顺序):
修复命令不依赖于特定环境。在命令中使用
ideviceinstaller
的完整路径。例如:/path/to/ideviceinstaller ...
如果您不知道完整路径,在常见的 *nix 系统上,您可以在交互式 SSH session.
中使用which ideviceinstaller
命令修复您的启动脚本,将
PATH
设置为与 non-interactive sessions 相同。尝试 运行 通过登录 shell 显式启用脚本(将
--login
开关与通用 *nix shells 一起使用):bash --login -c "ideviceinstaller ..."
如果命令本身依赖于特定的环境设置并且您无法修复启动脚本,则可以在命令本身中更改环境。那取决于远程系统的语法 and/or shell。在常见的 *nix 系统中,这有效:
PATH="$PATH;/path/to/ideviceinstaller" && ideviceinstaller ...
另一个(不推荐)是使用“shell”通道通过
SshClient.CreateShellStream
或SshClient.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 和伪终端自动执行命令会给您带来严重的副作用。