在 zsh Alias 中转义反斜杠和双引号
Escaping Backslashes and Double Quotes in zsh Alias
我正在尝试创建一个应该变成以下命令的别名:
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
简单易行
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"
在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
我无法让 "
或 \
逃脱。
您似乎将整个表达式的第一个和最后一个双引号视为 'surrounding' 引号,但这不是它在 zsh
或 bash
中的工作方式.相反,这是一个由一组带引号和不带引号的字符串组成的表达式,这些字符串由于相邻而连接在一起。
一个简短的例子。这个:
a=X b=Y c=Z
echo '$a'$b'$c'
将打印此:
$aY$c
只有 $a
和 $c
被单引号括起来,因此没有展开。
由于您的示例中的某些字符(例如 [
、{
)实际上并未被引用,因此 shell 尝试扩展它们。它在 zsh
中失败,因为默认行为是在 glob 没有匹配项时退出。
有几种方法可以修复它。
选项 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
不推荐这样做。有很多方法可以让它失控,因为我们指望 shell 以精确的方式忽略特殊字符。
选项 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"
这在 bash
中也应该有效,并且在那里是个好主意。
选项 3 - 正如@chepner 建议的那样,使用更具可读性的函数:
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'
}
这也适用于 bash
。
我正在尝试创建一个应该变成以下命令的别名:
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
简单易行
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"
在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
我无法让 "
或 \
逃脱。
您似乎将整个表达式的第一个和最后一个双引号视为 'surrounding' 引号,但这不是它在 zsh
或 bash
中的工作方式.相反,这是一个由一组带引号和不带引号的字符串组成的表达式,这些字符串由于相邻而连接在一起。
一个简短的例子。这个:
a=X b=Y c=Z
echo '$a'$b'$c'
将打印此:
$aY$c
只有 $a
和 $c
被单引号括起来,因此没有展开。
由于您的示例中的某些字符(例如 [
、{
)实际上并未被引用,因此 shell 尝试扩展它们。它在 zsh
中失败,因为默认行为是在 glob 没有匹配项时退出。
有几种方法可以修复它。
选项 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
不推荐这样做。有很多方法可以让它失控,因为我们指望 shell 以精确的方式忽略特殊字符。
选项 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"
这在 bash
中也应该有效,并且在那里是个好主意。
选项 3 - 正如@chepner 建议的那样,使用更具可读性的函数:
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'
}
这也适用于 bash
。