【问题标题】:Running a command on a remote machine over SSH using NSTask fails使用 NSTask 通过 SSH 在远程机器上运行命令失败
【发布时间】:2014-04-16 03:35:55
【问题描述】:

我正在尝试使用 this answer 中的技术通过 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:

所以似乎第一个值使用了——除非它是我想要被使用的值。有什么想法吗?

【问题讨论】:

  • 我知道 Cocoa 和 OS X,但在 Linux 机器上你必须通过 validusername@192.168.0.15@,而不是 :。此外,您尝试的第二个arguments = ... 向我表明,您在开头放置的ssh 是无关紧要的。这就像在命令行输入ssh ssh...ssh 命令将此 ssh 解释为主机名,但无法解析它。我不得不说我对您在第一次尝试时遇到的-- 错误感到困惑。
  • @Louis 我应该说我已经尝试过传统的user@host 方法,但仍然不起作用。这也让我感到困惑......
  • 您是否尝试将@"-t 'ps -C mpg123'" 分成两个参数?类似@"-t", @"ps -C mpg123"
  • 哇,这很有效@Louis。继续发布它作为答案!
  • 请仔细检查我的语法。正如我所说,这不是我曾经工作过的环境。我能够从其他情况下的经验中弄清楚。

标签: macos cocoa ssh nstask


【解决方案1】:

您应该将创建要传递给ssh 的参数的方式更改为:

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

您面临的问题是,您提供了一个参数列表,如果通过 shell 作为命令传递,这些参数看起来还不错。例如,您引用了 ps 命令。但是由于您遇到的错误,我推断启动您的任务的 API 是直接启动它,而不使用 shell。在不应该传递对 shell 有益的参数时,这是一个常见的错误(我有时会犯这种错误)。因此,当事情失败时,最好仔细检查一下:这个 API 是否通过 shell 启动我的可执行文件。

我还认为您必须使用validusername@192.168.0.15 而不是validusername:192.168.0.15,但您在评论中提到您已经使用过它并且没有任何区别。我提到这一点是为了完整性,以防其他读者不得不指出这一点。

【讨论】:

    猜你喜欢
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多