[英]Escaping Backslashes and Double Quotes in zsh Alias
I am trying to create an alias that should turn into the following command:我正在尝试创建一个应该变成以下命令的别名:
aws ssm start-automation-execution --document-name "AWS-StartEC2Instance" --document-version "\$DEFAULT" --parameters '{"AutomationAssumeRole":[""]}' --target-parameter-name InstanceId --targets '[{"Key":"ResourceGroup","Values":["DemoInstances"]}]' --max-errors "1" --max-concurrency "1" --region ap-southeast-1
It's straightforward to just do做起来很简单
alias startdemoinstances="aws ssm start-automation-execution --document-name "AWS-StartEC2Instance" --document-version "\$DEFAULT" --target-parameter-name InstanceId --targets "[{"Key":"ResourceGroup","Values":["DemoInstances"]}]" --max-errors "1" --max-concurrency "1" --region ap-southeast-1"
on bash, but on zsh, the command turns into在 bash 上,但在 zsh 上,命令变成
aws ssm start-automation-execution --document-name AWS-StartEC2Instance --document-version $DEFAULT --target-parameter-name InstanceId --targets '\''[{Key:ResourceGroup,Values:[DemoInstances]}]'\'' --max-errors 1 --max-concurrency 1 --region ap-southeast-1
I can't get the "
or the \
to escape.我无法让"
或\
逃脱。
It looks like you're treating the first and last double-quotes as 'surrounding' quotes for the entire expression, but that's not how it works in either zsh
or bash
.看起来您将第一个和最后一个双引号视为整个表达式的“环绕”引号,但这不是它在zsh
或bash
中的工作方式。 Instead, that's an expression consisting of a set of quoted and unquoted strings that are concatenated because they are adjacent.相反,这是一个由一组带引号和不带引号的字符串组成的表达式,这些字符串因为相邻而被连接起来。
A short example.一个简短的例子。 This:这个:
a=X b=Y c=Z
echo '$a'$b'$c'
will print this:将打印:
$aY$c
only the $a
and $c
are in single quotes, and are therefore not expanded.只有$a
和$c
在单引号中,因此不展开。
Since some of the characters in your example (eg [
, {
) are not actually quoted, the shell attempts to expand them.由于您的示例中的某些字符(例如[
, {
)实际上没有被引用,因此 shell 会尝试扩展它们。 It fails in zsh
since the default behavior is to exit if a glob has no matches.它在zsh
中失败,因为默认行为是在 glob 没有匹配项时退出。
There are several ways to fix it.有几种方法可以修复它。
Option 1 - make zsh behave like bash:选项 1 - 使 zsh 的行为类似于 bash:
unsetopt nomatch
alias startdemoinstances="aws ssm start-automation-execution --document-name "AWS-StartEC2Instance" --document-version "\$DEFAULT" --target-parameter-name InstanceId --targets "[{"Key":"ResourceGroup","Values":["DemoInstances"]}]" --max-errors "1" --max-concurrency "1" --region ap-southeast-1"
setopt nomatch
This is not recommended.不建议这样做。 There are a lot of ways for it to go haywire, since we're counting on the shell ignoring special characters in an exact way.有很多方法可以让 go 失控,因为我们指望 shell 以精确的方式忽略特殊字符。
Option 2 - escape internal double-quotes, so that the expression becomes one long string:选项 2 - 转义内部双引号,使表达式变成一个长字符串:
alias startdemoinstances="aws ssm start-automation-execution --document-name \"AWS-StartEC2Instance\" --document-version \"\$DEFAULT\" --target-parameter-name InstanceId --targets \"[{\"Key\":\"ResourceGroup\",\"Values\":[\"DemoInstances\"]}]\" --max-errors \"1\" --max-concurrency \"1\" --region ap-southeast-1"
This should also work in bash
, and would be a very good idea there.这也应该适用于bash
,这将是一个非常好的主意。
Option 3 - as @chepner suggested, use a much more readable function:选项 3 - 正如@chepner 建议的那样,使用更具可读性的 function:
function startdemoinstances {
aws ssm start-automation-execution \
--document-name 'AWS-StartEC2Instance' \
--document-version "$DEFAULT" \
--target-parameter-name 'InstanceId' \
--targets '[{"Key":"ResourceGroup","Values":["DemoInstances"]}]' \
--max-errors '1' \
--max-concurrency '1' \
--region 'ap-southeast-1'
}
This should also work in bash
.这也应该适用于bash
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.