目前,我们通过 AWS SSM 命令修补并重新启动大量 Windows 实例,但存在一个问题,即 SSM 代理并不总是签入。我的想法是加快速度,我可以在每个补丁上运行 while 循环组,拉动组中每个实例的正常运行时间。一旦所有实例都启动了 2 分钟,下一组将重新启动。我似乎无法解决如何正确创建 while 循环来完成此任务的简单问题。
当将以下命令作为 bash 脚本运行时,我收到一条错误,指出我试图在循环中使用“无效算术运算符”。我通过输出 $upTime 的值进行了测试,它是“18”。
这似乎是我浪费了太多时间的小混乱之一,有人很快就能指出我做错了什么。如果 $upTime 的输出是一个数字,我假设循环中的 less 会起作用。如果我只是将其硬设置为 18,它会正确循环,这让我认为这一定是 SSM 命令的一些奇怪的格式问题,但这应该是纯文本,并且从我的测试来看,没有空格通过。
#!/bin/bash
aws ec2 reboot-instances --instance-ids `aws ec2 describe-instances --filters "Name=tag:RebootGroup,Values=01" --query 'Reservations[].Instances[].InstanceId' --output text`
sleep 30
upTime=1
while [[ $upTime -le 120 ]]
do
ssmID=$(aws ssm send-command --document-name "AWS-RunPowerShellScript" --document-version "1" --targets '[{"Key":"tag:RebootGroup","Values":["01"]}]' --parameters '{"commands":["$wmi = Get-WmiObject -Class Win32_OperatingSystem ","$uptimeSeconds = ($wmi.ConvertToDateTime($wmi.LocalDateTime)-$wmi.ConvertToDateTime($wmi.LastBootUpTime) | select-object -expandproperty \"TotalSeconds\")","[int]$uptimeSeconds"],"workingDirectory":[""],"executionTimeout":["3600"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-west-2 --output text --query "Command.CommandId")
echo "Value of ssmID = $ssmID"
echo "Value of upTime before sleep = $upTime"
sleep 15
upTime=$(aws ssm list-command-invocations --command-id "$ssmID" --details --query "CommandInvocations[].CommandPlugins[].{Output:Output}" --output text)
echo "Value of upTime after command invocation = $upTime"
echo "Waiting for instance uptime of 2 minutes before continuing"
done
答案1
我敢打赌你那里有一个杂散的回车符:
$ upTime=$'42\r'
$ [[ $upTime -le 120 ]] && echo y || echo n
")syntax error: invalid arithmetic operator (error token is "
n
并且由于错误,[[
返回非零并且 while 循环结束得太快。
尝试这个:
printf "Value of upTime after command invocation = %q\n" "$upTime"
如果我是对的,您可以通过参数扩展删除 CR:
upTime=${upTime%$'\r'}
或使用 sed
upTime=$(aws ... | sed 's/\r$//')