Выполнение команды на удаленной машине через SSH с использованием NSTask завершается неудачно

Я пытаюсь использовать приемы из этого ответа для запуска команды на удаленной машине через SSH и сбора выходных данных. Это мой код:

dispatch_async(dispatch_queue_create("closet ping", NULL), ^{
    NSTask *task;
    task = [[NSTask alloc] init];
    [task setLaunchPath: @"/usr/bin/ssh"];

    NSArray *arguments;
    arguments = [NSArray arrayWithObjects:@"validusername:192.168.0.15", @"-t 'ps -C mpg123'", nil];
    [task setArguments: arguments];

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput: pipe];

    NSFileHandle *file;
    file = [pipe fileHandleForReading];

    [task launch];

    NSData *data;
    data = [file readDataToEndOfFile];

    NSString *string;
    string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
    NSLog (@"ping returned:\n%@", string);

    ...

Выполнение этого кода производит это в моей консоли XCode:

parker:192.168.0.15: illegal option --  
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-e escape_char] [-F configfile]
           [-I pkcs11] [-i identity_file]
           [-L [bind_address:]port:host:hostport]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-W host:port] [-w local_tun[:remote_tun]]
           [user@]hostname [command]
2014-04-15 13:09:56.640 NetworkBoard[26148:8443] ping returned:

Бег whereis ssh в консоли показывает /usr/bin/ssh - именно там, где я и ожидал. Кажется, первый аргумент в моем arguments массив почему-то используется как команда. Я попытался изменить это на это:

arguments = [NSArray arrayWithObjects:@"ssh", @"validusername:192.168.0.15", @"-t 'ps -C mpg123'", nil];

Но тогда это показано в консоли:

ssh: Could not resolve hostname ssh: nodename nor servname provided, or not known
2014-04-15 13:11:48.574 NetworkBoard[26280:2103] ping returned:

Таким образом, кажется, что используется первое значение - если это не значение, которое я хочу использовать. Есть идеи?

1 ответ

Решение

Вы должны изменить способ создания аргументов для передачи ssh к этому:

NSArray *arguments;
arguments = [NSArray arrayWithObjects:@"validusername:192.168.0.15", @"-t", @"ps -C mpg123", nil];

Проблема, с которой вы столкнулись, заключается в том, что вы приводили список аргументов, которые выглядели бы хорошо, если бы они передавались в виде команды через оболочку. Вы цитировали ps команда, например. Но с ошибкой, которую вы получили, я сделал вывод, что API, который запускал вашу задачу, запускал ее напрямую, без использования оболочки. Передача аргументов, которые полезны для оболочки, когда этого не следует делать, является распространенной ошибкой (которую я иногда делал сам). Поэтому, когда что-то не получается, хорошо проверить дважды: запускает ли этот API мой исполняемый файл через оболочку или нет.

Я также подумал, что вам придется использовать validusername@192.168.0.15 вместо validusername:192.168.0.15 но вы упомянули в комментарии, что вы использовали это, и это не имело никакого значения. Я упоминаю это для полноты на случай, если другие читатели будут вынуждены указать на это.

Другие вопросы по тегам