2011-06-03 34 views
8

Trong ứng dụng Cocoa của tôi, tôi đang cố gắng sử dụng NSTask để chạy một số lệnh Git cơ bản. Bất cứ khi nào tôi chạy một lệnh đòi hỏi quyền (khóa SSH) để truy cập từ xa (ví dụ git push, git pull), nó không thành công với các lỗi sau:NSTask và Git - Các vấn đề về quyền

Permission denied (publickey). The remote end hung up unexpectedly

Chạy các lệnh tương tự từ đầu cuối làm việc tốt, vì vậy tôi m nghĩ rằng đây có thể là vấn đề với NSTask không đặt biến môi trường sẽ được sử dụng ở đâu đó trong quá trình truy cập các khóa ssh. Tôi đã thử bằng tay thiết lập các biến HOMEUSER môi trường như thế này:

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

Nhưng điều này không có tác dụng. Có bất kỳ biến môi trường cụ thể nào mà tôi phải đặt trong NSTask để biến này hoạt động bình thường không?

EDIT: Nhờ mẹo của Dustin, tôi đã tìm hiểu thêm một chút trong việc tìm hiểu điều này. Tôi đã sử dụng lệnh env vào danh sách các biến môi trường cho phiên hiện tại của tôi và tôi thấy điều này:

SSH_AUTH_SOCK=/tmp/launch-DMQopt/Listeners 

Để kiểm tra, tôi sao chép con đường đó và đặt nó như là một biến môi trường của NSTask và chạy mã một lần nữa, và điều này thời gian nó hoạt động! Điều đó nói rằng, tôi chắc chắn rằng SSH_AUTH_SOCK thay đổi cho mỗi phiên vì vậy tôi không thể chỉ mã hóa nó. Làm thế nào để tự động tạo/lấy biến này?

+1

hãy thử theo cách khác, sử dụng 'env -i' trên dòng lệnh và xem bạn cần thêm bao nhiêu trở lại trước khi nó hoạt động. – Dustin

+0

Có thêm một chút nhờ mẹo của bạn, hãy đọc bài đăng đã chỉnh sửa của tôi :) – indragie

Trả lời

4

Bạn có thể thử và làm theo hướng dẫn "Wrapping rsync or SSH in an NSTask" (từ Ira), mà không đề cập đến SSH_AUTH_SOCK biến:

Since writing this post I've realised that I omitted an important additional step in setting up the environment variables for the NSTask.
In order to make passwordless key-based authentication work it's necessary to grab the SSH_AUTH_SOCK variable from the user's environment and include this in the NSTask's environment.
So, when setting environment variables for example;

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]; 

Tuy nhiên, OP indragie nhận xét:

I had tried this earlier but since it was being invoked with XCode, the SSH_AUTH_SOCK env var. wasn't being passed to it.
Opening the app from Finder corrects this issue.



With askPassPath being the path for the Askpass executable, which is included as part of the application’s main bundle. (In order to do this, find the executable under “Products” in xcode, and then drag it into “Copy Bundle Resources” on the main application’s target.)

// 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]]; 
+1

Tôi đã thử điều này trước đó nhưng vì nó đã được gọi với Xcode, SSH_AUTH_SOCK env var. đã không được chuyển cho nó. Mở ứng dụng từ Trình tìm kiếm sẽ khắc phục sự cố này. Cảm ơn bạn! – indragie

+0

@indragie: Tuyệt vời. Tôi đã bao gồm bình luận của bạn trong câu trả lời cho khả năng hiển thị nhiều hơn. – VonC

+0

@VonC Bạn có thể cho tôi biết biến askPassPath là gì không? –

Các vấn đề liên quan