Проблема NSTask с командой 'cat'

Я пытаюсь объединить файлы с помощью команды cat. Когда я использую это в терминале, все работает нормально:

cat /Users/Home/Desktop/test.mp3* > test.mp3

Попытка воспроизвести это с помощью NSTask выдает следующую ошибку:

Код :

NSArray *Args = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%@*",[TAFileName stringByDeletingPathExtension]],@">",[TAFileName stringByDeletingPathExtension],nil];
NSLog(@"%@",Args);
NSString *LaunchPath = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@""];
[self startTaskWithLaunchPath:LaunchPath andArguments:Args showingProcess:NO];

Выход NSLog:

(
"/Users/Home/Desktop/test.mp3*",
">",
"/Users/Home/Desktop/test.mp3"
)

Ошибка :

cat: /Users/Home/Desktop/test.mp3*: No such file or directory
cat: >: No such file or directory
cat: /Users/Home/Desktop/test.mp3: No such file or directory

«startTaskWithLaunchPath: andArguments: showProcess:» отлично работает со многими другими командами терминала, я на 100% уверен, что проблема не в этом.


person Bruno    schedule 23.12.2010    source источник


Ответы (2)


Проблема заключается в перенаправлении ввода и подстановке, которые обрабатываются оболочкой (обычно #!/bin/bash), а не командой cat. Таким образом, запуск задачи с аргументом для расширения "test.mp3*" в настоящее имя MP3, а затем перенаправление его в другое место - это не то, что задача может сделать.

Я бы порекомендовал посмотреть, можете ли вы вызвать сценарий оболочки напрямую, возможно, даже динамически создать его в своем приложении, а затем вызвать его в качестве аргумента для приложения bash. Тогда он должен делать то, что вам нужно.

person Michael Petrov    schedule 23.12.2010
comment
По какой-то причине я не получил уведомление о вашем ответе, так что большое спасибо. Хотя я не совсем понимаю. На самом деле нет другого места назначения, верно? Все это делается на моем рабочем столе (на самом деле зависит от того, какой файл пользователь перетаскивает в мое представление, но все это делается в одной папке). И запуск split работает нормально, даже если у split нет этого подстановочного знака. - person Bruno; 24.12.2010
comment
Ну, дело не в назначении, а в синтаксисе в оболочке Unix. Существуют инструменты (cat, mv, cp, echo), которые являются реальными приложениями, которые принимают аргументы (точные имена файлов и т. д.) и выполняют функцию — вывод своих данных. где-то. Кроме того, есть оболочки (bash, csh и т. д.), которые предоставляют такие возможности, как преобразование test.mp3* в реальный элемент test.mp3.12345 (если он существует), и оболочка также принимает вывод команды cat и позволяет вам сказать › somefile.mp3 для перенаправления вывода cat. Итак, вы пытаетесь использовать функцию оболочки, просто выполняя инструмент (cat). - person Michael Petrov; 24.12.2010
comment
Имеет смысл. Мне нужно использовать NSFileHandle для обработки ввода и вывода. Я надеюсь, что это сработает с использованием NSTimer, чтобы предотвратить зависание графического интерфейса (в настоящее время я обрабатываю вывод с помощью NSTimer в отдельном потоке). Большое спасибо (не могу поставить вам балл, так как я здесь новичок, мне нужно 15 репутации). - person Bruno; 24.12.2010
comment
Я бы порекомендовал запускать задачу в собственном NSThread, если это возможно, так она точно не будет блокироваться. И если вам нужен более продвинутый вывод и манипулирование файлами - вам лучше использовать программу, чтобы написать какой-то сценарий оболочки, а затем запустить его через оболочку bash. Это проще, чем кажется (записать файл во временную папку, выполнить его с помощью bash с тем же кодом). И вы можете найти множество руководств по этому вопросу в Google (скрипты bash). - person Michael Petrov; 24.12.2010
comment
Я не очень хорошо знаком с NSThreads и т. д., но когда я попытался запустить NSTask в отдельном потоке, это не решило мою проблему с графическим интерфейсом. Использование NSTimer в отдельном потоке работает нормально, независимо от того, насколько велик файл, с которым я работаю. Но создание собственных bash-скриптов выглядит отличной идеей. Я обязательно посмотрю на это. - person Bruno; 24.12.2010

Мне удалось решить проблему с помощью "/bin/sh". Это анализирует команду в оболочке и запускает ее таким образом. Использование этого метода по-прежнему выводит «Нет такого файла», но я решил это, изменив начальный рабочий каталог задачи.

Код для запуска задачи:

NSArray *Args = [NSArray arrayWithObjects:@"-c",[NSString stringWithFormat:@"cat %@.* >> %@",[[TAFileName lastPathComponent] stringByDeletingPathExtension],[[TAFileName lastPathComponent] stringByDeletingPathExtension]],nil];
NSString *LaunchPath = @"/bin/sh";
[self startTaskWithLaunchPath:LaunchPath andArguments:Args showingProcess:NO];

Код для смены каталога:

[TATask setCurrentDirectoryPath:[NSString stringWithFormat:@"%@/",[TAFileName stringByDeletingLastPathComponent]]];

Это решило все. Спасибо, Михаил, за помощь.

person Bruno    schedule 28.12.2010