NSTask和Git - 权限问题

ind*_*gie 9 git cocoa objective-c environment-variables nstask

在我的Cocoa应用程序中,我正试图NSTask运行一些基本的Git命令.每当我运行需要的权限(SSH密钥)来访问远程命令(例如git push,git pull)时,出现以下错误:

权限被拒绝(publickey).远程端意外挂断了

从终端运行相同的命令工作正常,所以我认为这可能是一个问题,NSTask因为没有设置在访问ssh密钥的过程中某处使用的环境变量.我尝试手动设置HOMEUSER环境变量,如下所示:

[task setEnvironment:[NSDictionary dictionaryWithObjectsAndKeys:NSHomeDirectory(), @"HOME", NSUserName(), @"USER", nil]];
Run Code Online (Sandbox Code Playgroud)

但这没有效果.我必须设置任何特定的环境变量NSTask才能正常工作吗?

编辑:感谢达斯汀的提示,我进一步了解了这一点.我用env命令列出了当前会话的环境变量,我发现了这个:

SSH_AUTH_SOCK=/tmp/launch-DMQopt/Listeners
Run Code Online (Sandbox Code Playgroud)

为了测试,我复制了该路径并将其设置为环境变量NSTask并再次运行代码,这次它起作用了!也就是说,我确定SSH_AUTH_SOCK每个会话都有变化,所以我不能只对它进行硬编码.如何动态生成/检索此变量?

Von*_*onC 4

您可以尝试按照教程“ Wrapping rsync or SSH in an NSTask ”(来自Ira),其中确实提到了SSH_AUTH_SOCK变量:

\n
\n

自从写这篇文章以来,我意识到我省略了为 NSTask 设置环境变量的一个重要的附加步骤。
\n为了使无密码的基于密钥的身份验证工作,有必要SSH_AUTH_SOCK从用户的环境中获取变量并将其包含在 NSTask 的环境中
\n因此,例如在设置环境变量时;

\n
\n
NSTask *task;\nNSDictionary *environmentDict = [[NSProcessInfo processInfo] environment];\n// Environment variables needed for password based authentication \nNSMutableDictionary *env = [NSMutableDictionary dictionaryWithObjectsAndKeys:\n                         @"NONE", @"DISPLAY",                           askPassPath, @"SSH_ASKPASS",\n                         userName,@"AUTH_USERNAME",\n                         hostName,@"AUTH_HOSTNAME",\n                         nil];\n \n// Environment variable needed for key based authentication\n[env setObject:[environmentDict objectForKey:@"SSH_AUTH_SOCK"] forKey:@"SSH_AUTH_SOCK"];\n \n// Setting the task\'s environment\n[task setEnvironment:env];\n
Run Code Online (Sandbox Code Playgroud)\n

然而,OP indragie评论道:

\n
\n

我之前曾尝试过此操作,但由于它是使用 XCode 调用的,因此SSH_AUTH_SOCK环境变量。没有被传递给它。
\n从 Finder 打开应用程序可以纠正此问题

\n
\n
\n
\n
\n

作为askPassPath Askpass 可执行文件的路径,它作为 application\xe2\x80\x99s 主捆绑包的一部分包含在内。(为此,请在 xcode 中的 \xe2\x80\x9cProducts\xe2\x80\x9d 下找到可执行文件,然后将其拖到主应用程序上的 \xe2\x80\x9cCopy Bundle Resources\xe2\x80\x9d 中\ xe2\x80\x99s 目标。)

\n
\n
// Get the path of the Askpass program, which is\n// setup to be included as part of the main application bundle\nNSString *askPassPath = [NSBundle pathForResource:@"Askpass"\n              ofType:@"" \n              inDirectory:[[NSBundle mainBundle] bundlePath]];\n
Run Code Online (Sandbox Code Playgroud)\n