I was trying to use the SSH.NET NuGet package to remotely execute a command to grab an app version that is installed on one iPhone connected to a Mac.
If executed on the Mac itself with below command, will get me its version:
ideviceinstaller -l|grep <bundleIdOfMyAppPackage>
So I build a small utility in C# with this package, hoping that I would leverage it. However, all I get is just an empty string. Would anyone let me know what I could do to get the result I want ? Thank you !
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();
}
The error that I've got from command.Error
is
zsh1: command not found ideviceinstaller`
which is weird because I can see ideviceinstaller
inside that folder if I browse to there.
I've got it working thanks to @Martin Prikryl by changing the command to:
/usr/local/bin/ideviceinstaller -l|grep <myAppBundleId>
The SSH.NET SshClient.CreateCommand
(or SshClient.RunCommand
) does not run shell in "login" mode and does not allocate a pseudo terminal for the session. As a consequence a different set of startup scripts is (might be) sourced (particularly for non-interactive sessions, .bash_profile
is not sourced), than in your regular interactive SSH session. And/or different branches in the scripts are taken, based on an absence/presence of TERM
environment variable.
Possible solutions (in preference order):
Fix the command not to rely on a specific environment. Use a full path to ideviceinstaller
in the command. Eg:
/path/to/ideviceinstaller ...
If you do not know the full path, on common *nix systems, you can use which ideviceinstaller
command in your interactive SSH session.
Fix your startup scripts to set the PATH
the same for both interactive and non-interactive sessions.
Try running the script explicitly via login shell (use --login
switch with common *nix shells):
bash --login -c "ideviceinstaller ..."
If the command itself relies on a specific environment setup and you cannot fix the startup scripts, you can change the environment in the command itself. Syntax for that depends on the remote system and/or the shell. In common *nix systems, this works:
PATH="$PATH;/path/to/ideviceinstaller" && ideviceinstaller ...
Another (not recommended) is to use "shell" channel to execute the command via SshClient.CreateShellStream
or SshClient.CreateShell
as these allocate pseudo terminal
ShellStream shellStream = client.CreateShellStream(string.Empty, 0, 0, 0, 0, 0); shellStream.Write("ideviceinstaller\\n"); while (true) { string s = shellStream.Read(); Console.Write(s); }
Using the shell and pseudo terminal to automate a command execution can bring you nasty side effects.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.