2

I am trying to wrap rsync in NSTask and use the exclude option to not sync hidden files (dot files). I know this works at the command line:

rsync -az --exclude='.*' source destination

My NSTask is defined as follows:

NSTask *rsyncTask;
rsyncTask = [[NSTask alloc] init];
[rsyncTask setLaunchPath: @"/usr/bin/rsync"];

NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"-az", @"--exclude='.*'", source, destination, nil];
[rsyncTask setArguments: arguments];

Without the exclude argument things work fine. In fact things work fine with the above definition but hidden files are still copied.

I have tried:

  • escaping the single ticks with a backslash
  • using escaped double quotes
  • using two backslashes to escape the escaping backslash
  • not using --exclude= but just --exclude with a separate array element that is @"'.*'"

Nothing seems to get the results I want.

Any suggestions welcome.

Wilersh
  • 85
  • 1
  • 5

2 Answers2

2

For anyone who comes across this looking for how to exclude multiple files, it turns out you need a separate --exclude for each file/directory you wish to exclude. On the command line the --exclude={file1,dir1/dir2,file2,dir1/dir\ with\ spaces} pattern works, but that format does not play nice with NSTask. For NSTask (swift) this would be:

task.arguments = ["-FLAGS", "--exclude", "file1", "--exclude", "dir1/dir2", "--exclude", "file2", "--exclude", "dir1/dir with spaces", "SRC", "DST"]

Also note that NSTask does not require spaces to be escaped. From the docs, "The NSTask object converts both path and the strings in arguments to appropriate C-style strings (using fileSystemRepresentation) before passing them to the task via argv[]) . The strings in arguments do not undergo shell expansion, so you do not need to do special quoting, and shell variables, such as $PWD, are not resolved."

KernelSanders
  • 387
  • 3
  • 10
1

Try using just --exclude with a separate argument that is @".*" (without single quotes).

Since you are passing arguments directly to the task, you don't need to quote or escape things like you would at a command line. That's because at the command line, the shell is parsing what you type, but in this case there is no shell.

benzado
  • 82,288
  • 22
  • 110
  • 138
  • You can also continue passing the single argument with the same modification, for the same reason. In the original command line, you used single quotes to protect the glob pattern from the shell, which responded by stripping out the single quotes and doing nothing more. Since you are now not working through a shell, there is nothing you need to protect with single quotes and nothing to strip them out, so you should simply leave them out in the first place: `@"--exclude=.*"` . – Peter Hosey Jan 14 '11 at 08:49