Выполните терминальную команду из приложения Какао

Связанный вопрос, похоже, очень хорошо его охватывает: CPU просто нет. 32-разрядный процессор имеет свои собственные арифметические операции, настроенные для 32-разрядных регистров. Процессор предпочитает работать в своем любимом размере, и для таких операций копирование небольшого значения в регистр собственного размера дешево. (Для архитектуры x86 32-разрядные регистры названы так, как если бы они были расширенными версиями 16-разрядных регистров (eax - ax, ebx - bx и т. Д.), См. x86 целочисленные инструкции ).

Для некоторых чрезвычайно распространенных операций, в частности векторной / float-арифметики, могут быть специализированные инструкции, которые работают с другим типом или размером регистра. Для чего-то вроде короткого, заполнение (до) 16 бит нулей имеет очень небольшую стоимость исполнения и добавление специализированных инструкций, вероятно, не стоит времени или места на уме (если вы хотите получить действительно физическое о том, почему, я не уверен, что они будут занимать реальное пространство, но он становится более сложным).

200
задан Jonas 2 February 2011 в 15:41
поделиться

5 ответов

Можно использовать NSTask. Вот пример, который работал бы' /usr/bin/grep foo bar.txt'.

int pid = [[NSProcessInfo processInfo] processIdentifier];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;

NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/bin/grep";
task.arguments = @[@"foo", @"bar.txt"];
task.standardOutput = pipe;

[task launch];

NSData *data = [file readDataToEndOfFile];
[file closeFile];

NSString *grepOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog (@"grep returned:\n%@", grepOutput);

NSPipe и NSFileHandle используются для перенаправления стандартного вывода задачи.

Для более подробной информации о взаимодействии с операционной системой из Вашего приложения Objective C, Вы видите этот документ о Центре разработки Apple: Взаимодействие с Операционной системой .

Редактирование: Включенный фиксируют для проблемы NSLog

, Если Вы используете NSTask для выполнения утилиты командной строки через удар, тогда необходимо включать эту волшебную строку для хранения работы NSLog:

//The magic line that keeps your log where it belongs
task.standardOutput = pipe;

объяснение здесь: https://web.archive.org/web/20141121094204/https://cocoadev.com/HowToPipeCommandsWithNSTask

282
ответ дан Daniel 23 November 2019 в 05:06
поделиться

ветвление , должностное лицо , и ожидает , должен работать, если Вы действительно не ищете особенный метод Objective C. fork создает копию в настоящее время запускающей программы, exec замены, из которых в настоящее время запускающая программа с новой, и wait ожидает подпроцесса для выхода. Например (без любой проверки ошибок):

#include <stdlib.h>
#include <unistd.h>


pid_t p = fork();
if (p == 0) {
    /* fork returns 0 in the child process. */
    execl("/other/program/to/run", "/other/program/to/run", "foo", NULL);
} else {
    /* fork returns the child's PID in the parent. */
    int status;
    wait(&status);
    /* The child has exited, and status contains the way it exited. */
}

/* The child has run and exited by the time execution gets to here. */

существует также система , который выполняет команду, как будто Вы ввели его из командной строки оболочки. Это более просто, но Вы имеете меньше контроля над ситуацией.

я предполагаю, что Вы работаете над приложением Mac, таким образом, ссылки к документации Apple для этих функций, но они - весь POSIX, таким образом, необходимо быть должны использовать их в любой совместимой POSIX системе.

14
ответ дан Maxim Veksler 23 November 2019 в 05:06
поделиться

Существует также старая добрая система POSIX ("повторяют-en '\007'");

11
ответ дан nes1983 23 November 2019 в 05:06
поделиться

Или так как Objective C просто C с некоторым уровнем OO на вершине, можно использовать posix дубликаты:

int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);
int execle(const char *path, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execlp(const char *file, const char *arg0, ..., const char *argn, (char *)0);
int execlpe(const char *file, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]); 

Они включены от unistd.h заголовочного файла.

2
ответ дан Paulo Lopes 23 November 2019 в 05:06
поделиться

в духе совместного использования... это - метод, который я использую часто для выполнения сценариев оболочки. можно добавить сценарий к пакету продукта (в фазе копии сборки) и затем иметь сценарий быть считанными и выполненными во времени выполнения.примечание: этот код ищет сценарий в подпути privateFrameworks. предупреждение: это могло быть угрозой безопасности для развернутых продуктов, но для нашей внутренней разработки это - простой способ настроить простые вещи (как который хост rsync к...), не перекомпилировав приложение, но просто редактируя сценарий оболочки в пакете.

//------------------------------------------------------
-(void) runScript:(NSString*)scriptName
{
    NSTask *task;
    task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/sh"];

    NSArray *arguments;
    NSString* newpath = [NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] privateFrameworksPath], scriptName];
    NSLog(@"shell script path: %@",newpath);
    arguments = [NSArray arrayWithObjects:newpath, 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 (@"script returned:\n%@", string);    
}
//------------------------------------------------------

Править: Включенный фиксируют для проблемы NSLog

Если Вы используете NSTask для выполнения утилиты командной строки через удар, то необходимо включать эту волшебную строку для хранения работы NSLog:

//The magic line that keeps your log where it belongs
[task setStandardInput:[NSPipe pipe]];

В контексте:

NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
//The magic line that keeps your log where it belongs
[task setStandardInput:[NSPipe pipe]];

Объяснение здесь: http://www.cocoadev.com/index.pl?NSTask

40
ответ дан Steve McLeod 23 November 2019 в 05:06
поделиться