【问题标题】:NSTask and Git -- Permissions issuesNSTask 和 Git——权限问题
【发布时间】:2011-09-07 12:51:22
【问题描述】:

在我的 Cocoa 应用程序中,我尝试使用 NSTask 运行一些基本的 Git 命令。每当我运行需要权限(SSH 密钥)才能访问远程(例如git pushgit pull)的命令时,它都会失败并出现以下错误:

权限被拒绝(公钥)。远端意外挂断

从终端运行相同的命令效果很好,所以我认为这可能是NSTask 没有设置将在访问 ssh 密钥过程中某处使用的环境变量的问题。我尝试像这样手动设置HOMEUSER 环境变量:

[task setEnvironment:[NSDictionary dictionaryWithObjectsAndKeys:NSHomeDirectory(), @"HOME", NSUserName(), @"USER", nil]];

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

编辑:多亏了达斯汀的提示,我在弄清楚这一点上有了进一步的了解。我使用env 命令列出了我当前会话的环境变量,我发现了这个:

SSH_AUTH_SOCK=/tmp/launch-DMQopt/Listeners

为了测试,我复制了该路径并将其设置为NSTask 的环境变量,然后再次运行代码,这次成功了!也就是说,我确信SSH_AUTH_SOCK 会针对每个会话进行更改,因此我不能只对其进行硬编码。如何动态生成/检索此变量?

【问题讨论】:

  • 换一种方式试试,在命令行上使用env -i,看看你需要添加多少才能正常工作。
  • 感谢您的提示,进一步了解了,请阅读我编辑的帖子 :)

标签: objective-c cocoa git environment-variables nstask


【解决方案1】:

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

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

NSTask *task;
NSDictionary *environmentDict = [[NSProcessInfo processInfo] environment];
// Environment variables needed for password based authentication 
NSMutableDictionary *env = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                         @"NONE", @"DISPLAY",                           askPassPath, @"SSH_ASKPASS",
                         userName,@"AUTH_USERNAME",
                         hostName,@"AUTH_HOSTNAME",
                         nil];

// Environment variable needed for key based authentication
[env setObject:[environmentDict objectForKey:@"SSH_AUTH_SOCK"] forKey:@"SSH_AUTH_SOCK"];

// Setting the task's environment
[task setEnvironment:env];

但是,OP indragie cmets:

我之前尝试过这个,但是因为它是用 XCode 调用的,SSH_AUTH_SOCK env var。未传递给它。
从 Finder 打开应用程序可解决此问题



askPassPath 是 Askpass 可执行文件的路径,它包含在应用程序的主包中。 (为此,在 xcode 中的“Products”下找到可执行文件,然后将其拖到主应用程序目标上的“Copy Bundle Resources”中。)

// Get the path of the Askpass program, which is
// setup to be included as part of the main application bundle
NSString *askPassPath = [NSBundle pathForResource:@"Askpass"
              ofType:@"" 
              inDirectory:[[NSBundle mainBundle] bundlePath]];

【讨论】:

  • 我之前尝试过这个,但是因为它是用 Xcode 调用的,所以 SSH_AUTH_SOCK 环境变量。没有被传递给它。从 Finder 打开应用程序可解决此问题。谢谢!
  • @indragie:太好了。我已将您的评论包含在答案中以提高知名度。
  • @VonC 你能告诉我 askPassPath 是什么变量吗?
  • @user76859403 当然,我已经恢复了链接,并在编辑后的答案中包含了askPassPath
  • @VonC 好的..这似乎是我的问题。使用 Mac OSx Xcode 和 NSTask.. --> ssh_askpass: exec(/usr/libexec/ssh-askpass): 没有这样的文件或目录。主机密钥验证失败。我想我将不得不找到另一个解决方案。 (我的系统上不存在该文件,但它一直在寻找它。我正在尝试 GIT 克隆)。你所做的那个代码编辑也给了我零。
猜你喜欢
  • 2014-04-20
  • 2011-07-24
  • 2020-03-04
  • 2019-01-10
  • 1970-01-01
  • 2016-11-21
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
相关资源
最近更新 更多