将 Bash 子 shell 的输出返回给 OSX "defaults" 实用程序时,如何保持单引号完整?

How do I keep single quotes intact when returning the output of a Bash subshell to the OSX "defaults" utility?

Context/Goal:

我正在尝试通过 OSX defaults 实用程序将数组写入 .plist 文件中的键。我的目标是用我选择的内容重写数组,而不是修改其现有内容。新内容是另一个命令的产物,应该是 shell 中单引号 space 分隔的字符串,每个对应一个数组元素。

我有 bash 3.2.57 和 OSX 10.10。

问题:

我似乎无法使 bash 的引用文字扩展正常工作。在这些示例中,我已将通过 subshell 使用的命令简化为 echo。有问题的行为是一样的。

例如,如果我这样写整个数组:

/usr/bin/defaults write com.apple.systemuiserver menuExtras -array 'foo bar' 'baz quux'

我可以读出来,像这样:

/usr/bin/defaults read com.apple.systemuiserver menuExtras
(
    "foo bar",
    "baz quux"
)

defaults 实用程序添加了双引号。

没关系。但是,如果我使用 subshell 生成数组内容,就会出错:

/usr/bin/defaults write com.apple.systemuiserver menuExtras -array $( echo -e 'foo bar' 'baz quux' )
/usr/bin/defaults read com.apple.systemuiserver menuExtras
(
    foo,
    bar,
    baz,
    quux
)

它检测字符串中的 space 作为分隔字段。好吧,我想,也许这太天真了; Bash 会尽可能地删除单引号,所以我需要 "hint" 它应该保留它们。

然后我尝试了我能想到的 Bash 的所有文字引用建议组合,结果相同。以下所有内容,如果分配给一个变量并 echoed,产生 'foo bar',引号保持不变。

$( echo -e "'foo bar'" )
$( echo -e "\x27foo bar\x27" )
$( echo -e '\x27foo bar\x27' )
$( echo $'\'foo bar\'' )
$( echo \'foo bar\' )
$( echo \''foo bar'\' )
$( echo "'"'foo bar'"'" )
$( echo ''"'"'foo bar'"'"'' )

问题:

如何从子 shell 中获取一系列单引号字符串并将其引号完整地放入 bash 命令中,以便 defaults 可以在不使用的情况下使用它弄乱字段分隔符并在不应该的时候拆分 spaces?

subshell 需要能够 return 多个引用的数组元素。我需要使用 shell,理想情况下只是 POSIX shell 功能(这是更大脚本的一部分)。如果可能的话,我宁愿避免像将东西存储在临时文件或 <(...) 按需管道中这样的黑客行为。字符串也需要是单引号,而不是双引号,因为它们的内容有时可能包含双引号,我不想与引号转义两次打架。

您需要引用扩展:

usr/bin/defaults write com.apple.systemuiserver menuExtras \
                       -array "$( echo 'foo bar' )"

(我从 echo 中删除了 -e 参数,因为它没有任何效果。)

我不清楚您对 -array 参数的预期效果。通常你会将它与多个值一起使用:

usr/bin/defaults write com.apple.systemuiserver menuExtras \
                       -array "$(echo 'one two')" \
                              "$(echo 'buckle my shoe')"

进一步搞乱得到了答案:xargs 而不是子 shell:

echo \'foo bar\' \'baz quux\' | xargs  /usr/bin/defaults write com.apple.systemuiserver menuExtras -array