在 osx bash 中转义多层级联的单引号和双引号

Escaping many layers of cascaded single and double quotes in osx bash

我使用 Mac(osx sierra)并且我一直在学习如何使用 bash。我正在尝试新的东西,因为我要掌握一些概念。这次我正在试验函数和别名。但是后来我无法解决这个问题:

我首先将此函数回显到 .profile 中,以便轻松地将新别名和函数插入到 .profile 文件中。

function editprofile(){
echo "$@" >> ~/.profile
}

此函数对于某些别名插入非常有效。但是在我尝试为使我的 mac 休眠的脚本(下面的脚本)插入别名之后,我意识到该函数使用级联单引号和双引号造成了一些困难。我相信大多数使用多层单引号和双引号的脚本都会出现这种情况。

osascript -e 'tell application "Finder" to sleep' && exit

下面的代码是我尝试使用我的函数将上面的代码作为别名插入到 .profile 中。

editprofile 'alias _sleep=' "'" 'osascript -e' "'" 'tell application "Finder" to sleep' "'" '&& exit' "'"

问题是当第二个脚本回显到 .profile 文件时,我仍然应该保留一些转义字符,否则 bash 会错误地解释代码。我认为可能其他具有这么多层引号的脚本也会出现这种情况,所以我想问一下是否有任何解决方法。

P.S。 在相关说明中,当我键入以下内容时似乎是:

function editprofile(){echo "$@" >> ~/.profile}

而不是这个:

function editprofile(){
echo "$@" >> ~/.profile
}

进入 .profile 文件,脚本不起作用。是换行的原因吗?

假设你有一个函数,而不是一个别名:

_sleep() { osascript -e 'tell application "Finder" to sleep' && exit; }

...您可以使用 declare -f 发出其文本。因此:

declare -f _sleep >>~/.profile

...或者,使用您现有的 editprofile 函数:

editprofile "$(declare -f _sleep)"

最简单的方法就是:在您的本地 shell 中定义函数,然后让 shell 自己完成发出它的工作——然后 发出的引用content 所以它不会将字段拆分为单独的参数(然后将这些参数单独评估为 globs)。


如果您不想走那条路,有一些方法可用;他们只是不同程度的不愉快。

printf -v cmd_var '%q ' osascript -e 'tell application "Finder" to sleep' 

...会将正确引用的内容放入 "$cmd_var"。然后你可以:

printf -v sleep_def '_sleep() { %s && exit; }' "$cmd_var"

...这将在 sleep_dev 中为您提供一个函数声明,可以 evaled 以在本地执行它,或附加到您的 .profile, &c.

editprofile "$sleep_def"

...将在这种情况下表现得当。