How to handle (e.g. correctly escape) parens in a ‘defaults write …’ key value

command linedefaults

TL;DR

In defaults write <domain> <key> <value>, how do I provide a <value> that contains parens; i.e. "round" brackets, "(" and ")" ?

Full Bhoona

I'm using defaults to redirect screen captures to a specific directory. That I can do fine, and have many times in the past, but I'm running into a problem when the target directory has parentheses in its pathname. So I'm doing something like:

$ defaults write com.apple.screencapture location <dirname-with-parens-in-it>

and I'm getting an error of the form:

<ba bla bla> Could not parse: <dirname-with-parens-in-it>.  Try single-quoting it.

But I get that despite trying all of the following (and a bunch more besides). In this, assume the name of the (pre-existing) directory in question is, literally, dirname(with)parens. My attempts and responses:

$ defaults write com.apple.screencapture location dirname\(with\)parens
<bla bla bla> Could not parse: dirname(with)parens.  Try single-quoting it.

$ defaults write com.apple.screencapture location 'dirname\(with\)parens'
<bla bla bla> Could not parse: dirname(with)parens.  Try single-quoting it.

And I repeated both, three times each, replacing the single \ with \\, \\\, and \\\\. Same error.

Notice however that the error does seem to suggest that the shell globbing itself is working fine, because 'defaults' is seeing the unescaped "(" and ")" correctly. And if directory name/path contains not parens but rather whitespace, then a simple \-escape works fine (as does quoting). Finally, I observe that for shell commands, like "mkdir", either of \-escaping parens, or quoting them, also work:

$ mkdir dirname\(with\)parens
$ ls -ld dirname*
drwxr-xr-x  2 jonyive demigods  68 Oct  3 10:56 dirname(with)parens

So a likely suspect is defaults itself. man defaults doesn't offer much, saying only that says only that, "value must be a property list, and must be enclosed in single quotes". And even that's a lie. In practice it only must be in single quotes if it contains anything funky, and even there, if the funkiness is whitespace, \-escaping will do. And of course, if the funkiness is parens, then not even single quoting appears to work.

So, any ideas? Thanks!

P.S. I'm aware of and have used workarounds. For example, I can create a non-troublesome symlink to the parens-infested actual directory, and just give defaults the symlink as the <value>. But I'd really like to get to the bottom of this.

Best Answer

To escape parens successfully in the defaults command you have to use quotes and inside the quotes single quotes:

Example:

defaults write com.apple.screencapture location "'/Users/user/Desktop/(Screenshots)'"