1

I try concatenating files using the cat command. When I use this in the terminal, everything works fine :

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

Trying to reproduce this using an NSTask, gives me the error below :

Code :

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 output :

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

Error :

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

The "startTaskWithLaunchPath: andArguments: showingProcess:" works fine with lots of other terminal commands, I'm 100% sure that's not the problem.

Bruno
  • 87
  • 1
  • 9

2 Answers2

1

The problem is input redirection and globbing, which is handled by the shell (typically #!/bin/bash) and not by the cat command. So starting a task with an argument to expand "test.mp3*" into a real MP3 name and then redirect it to a different location is not something that a task can do.

I would recommend seeing if you can call a shell script directly, perhaps even dynamically create it in your app - and then call it as an argument to the bash application. Then it should do what you need.

Michael Petrov
  • 2,247
  • 15
  • 15
  • For some reason I didn't get notified about your reply, so thanks a lot. I don't completely understand though. There isn't really an other destination, right? It's all done on my desktop (actually depends on what file the user drags into my view, but it's all done in one folder). And running split works fine, even though split doesn't have that wildcard. – Bruno Dec 24 '10 at 01:22
  • Well it's not about the destination - it's about the syntax in the Unix shell.There are tools ("cat","mv","cp","echo") which are real applications that take arguments (exact file names, etc) and perform a function - outputting their data somewhere. Then there are shells (bash, csh, etc) which provide capabilities such as expanding "test.mp3*" into a real item "test.mp3.12345" (if it exists), and the shell also takes the cat command output and allows you to say "> somefile.mp3" to redirect the cat output. So you're trying to use a function of the shell while simply executing a tool ("cat"). – Michael Petrov Dec 24 '10 at 04:34
  • Makes sense. I need to use an NSFileHandle for handling both input and output. I hope this is gonna work using an NSTimer to prevent the GUI from becoming unresponsive (I currently handle output using an NSTimer on a separate thread). Thanks a lot (I can't give you a point up as I'm very new here, I need 15 reputation). – Bruno Dec 24 '10 at 13:26
  • I would recommend running the task in its own NSThread if possible, that way it definitely will not block. And if you do want more advanced output and manipulation of files - you're better off using a program to write some kind of a shell script and then run it through the bash shell. It's easier than it sounds (write file to a temp location, execute it using bash with the same code). And you can Google plenty of tutorials on it ("bash scripting"). – Michael Petrov Dec 24 '10 at 14:20
  • I'm not very familiar with NSThreads etc., but when I tried running an NSTask in a seperate thread, it didn't solve my GUI problem. Using an NSTimer in a separate thread works fine, no matter how big the file is I'm handling. But creating my own bash scripts looks like an awesome idea though. I'm definitely going to look into that. – Bruno Dec 24 '10 at 17:34
0

I managed to solve the problem using "/bin/sh". This parses a command into a shell and runs it like that. Using this method still outputted "No such file", but I solved that by altering the task initial working directory.

Code for launching the task :

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

Code to change the directory :

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

That solved everything. Thanks, Michael, for your help.

Bruno
  • 87
  • 1
  • 9