Команды терпят неудачу с «<command> not found», когда выполняются с использованием S SH. NET CreateCommand в C# - PullRequest
3 голосов
/ 04 марта 2020

Я пытался использовать S SH. NET пакет NuGet для удаленного выполнения команды, чтобы получить версию приложения, установленную на одном iPhone, подключенном к Ma c .

Если выполнится на самом Ma c с помощью команды ниже, я получу его версию:

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: команда не найдена ideviceinstaller`

, которая странно, потому что я могу видеть ideviceinstaller внутри этой папки, если захожу туда.


У меня все работает благодаря @Martin Prikryl, изменив команду на:

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

1 Ответ

2 голосов
/ 04 марта 2020

S SH. NET SshClient.CreateCommand (или SshClient.RunCommand) не запускает оболочку в режиме «входа в систему» ​​и не выделяет псевдотерминал для сессия. Как следствие, другой набор сценариев запуска (может быть) получен (особенно для неинтерактивных сеансов, .bash_profile не получен), чем в вашем обычном интерактивном сеансе S SH. И / или различные ветви в сценариях используются на основании отсутствия / присутствия TERM переменной среды.

Возможные решения (в порядке предпочтения):

  1. Исправлена ​​команда не полагаться на конкретную c среду. Используйте полный путь к ideviceinstaller в команде. Например:

    /path/to/ideviceinstaller ...
    

    Если вы не знаете полного пути, в распространенных * системах nix вы можете использовать команду which ideviceinstaller в интерактивном сеансе S SH.

  2. Исправьте сценарии запуска, чтобы установить PATH одинаково для интерактивных и неинтерактивных сеансов.

  3. Попробуйте запустить сценарий явно через оболочку входа (используйте --login переключаться с обычными * nix-оболочками):

    bash --login -c "ideviceinstaller ..."
    
  4. Если сама команда основана на определенной настройке среды c и вы не можете исправить сценарии запуска, вы можете изменить среду в сама команда. Синтаксис для этого зависит от удаленной системы и / или оболочки. В обычных * nix системах это работает:

    PATH="$PATH;/path/to/ideviceinstaller" && ideviceinstaller ...
    
  5. Еще один (не рекомендуется) - использовать канал «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);
    }
    

    Использование оболочки и псевдотерминала для автоматизации выполнения команды может привести к неприятным побочным эффектам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...