Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interactive Shell Cocoa Application (NSTask)

I am trying to figure out how to pass input to a NSTask when prompted.

Example:

I do something like

kinit username@DOMAIN

and I get a "enter Password" prompt. I want to be able to supply the password to that NSTask.

Does anyone know how to do this? (Basically automating the process through a cocoa app).

Thanks!

like image 790
user754905 Avatar asked Aug 21 '12 21:08

user754905


1 Answers

Usually, command line applications read input from the command line via the standard input. NSTask provides a method setStandardInput: for setting a NSFileHandle or a NSPipe.

You could try something like:

NSTask *task = // Configure your task

NSPipe *inPipe = [NSPipe pipe];
[task setStandardInput:inPipe];

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

NSFileHandle *writer = [inPipe fileHandleForWriting];
NSFileHandle *reader = [outPipe fileHandleForReading];
[task launch]

//Wait for the password prompt on reader [1]
NSData *passwordData = //get data from NSString or NSFile etc.
[writer writeData:passwordData];

See NSFileHandle for methods for waiting for data on the reader NSFileHandle.

However, this is just an untested example showing the general way of solving this problem when having command line tools using prompts. For your specific problem, there might be another solution. The kinit command allows the argument --password-file=<filename> which can be used for reading the password from an arbitrary file.

From man kinit:

--password-file=filename

read the password from the first line of filename. If the filename is STDIN, the password will be read from the standard input.

The manual provides a third solution: Provide --password-file=STDIN as argument to your NSTask and there will be no password prompt. This eases up the process of providing the password via an NSPipe hence you do not need to wait on the standard output for the password prompt.

Conclusion: When using the third solution it is much easier:

  1. Configure your task with the --password-file=STDIN parameter
  2. Create a NSPipe
  3. Use it as standard input for your task
  4. launch the task
  5. write the password data to the pipe via [pipe fileHandleForWriting] (NSFileHandle)
like image 115
TobiasMende Avatar answered Nov 08 '22 23:11

TobiasMende