本地Linux与AWS EC2交互:通过EICE远程执行命令的AWS CLI方案
问题
我编写了一个Linux shell脚本(script.sh),通过AWS命令行工具(CLI)访问AWS账户,并借助EC2 Instance Connect Endpoint(EICE)与EC2实例建立连接。现需了解:连接建立后,脚本中应使用哪条AWS CLI命令向EC2实例发送Linux命令,并在终端获取执行结果?以下是脚本代码:
#!/bin/bash # 步骤1 echo "正在连接AWS账户..." export AWS_ACCESS_KEY_ID="00000000000" export AWS_SECRET_ACCESS_KEY="000000000000" sleep 3 echo "连接已建立。" # 步骤2 # 获取实例的JSON格式返回结果 access_json=$(aws ec2 describe-instances --region us-east-1) # 使用jq提取InstanceId的值 instance_id=$(echo "$access_json" | jq -r '.Reservations[0].Instances[0].InstanceId') # 步骤3 # 建立与实例的连接 echo "正在连接EC2实例..." aws ec2-instance-connect ssh --instance-id $instance_id --connection-type eice --region us-east-1 echo "连接已建立。" # 步骤4 # 需使用哪条AWS CLI命令通过已建立的连接向EC2实例发送Linux命令?
解决方案
首先明确:你当前步骤3的aws ec2-instance-connect ssh是启动交互式SSH会话,执行后脚本会停在会话中,直到手动退出,后续步骤4的代码不会自动执行。要在脚本中自动化发送命令并获取结果,有两种合适的方式:
方式1:直接通过aws ec2-instance-connect ssh执行单条命令
无需进入交互式会话,直接在命令后附加要执行的Linux命令,命令执行完成后自动返回结果到终端:
# 替换原步骤3+4:直接执行命令并获取结果 echo "正在执行实例内命令..." aws ec2-instance-connect ssh --instance-id $instance_id --connection-type eice --region us-east-1 -- "ls -l /home"
- 末尾的
--用于分隔AWS CLI参数和实例内执行的命令,避免命令中的参数被AWS CLI解析。 - 该方式适合快速执行单条或简单命令组合。
方式2:使用AWS SSM send-command(更适合自动化场景)
如果需要更稳定的自动化执行(无需依赖SSH端口开放、支持批量执行、可记录执行日志等),推荐使用AWS Systems Manager的send-command命令,它与EICE兼容,无需建立交互式会话:
# 步骤4:发送命令并获取结果 echo "通过SSM发送命令..." # 发送命令并记录命令ID command_id=$(aws ssm send-command \ --instance-ids $instance_id \ --document-name "AWS-RunShellScript" \ --parameters commands="ls -l /home" \ --region us-east-1 \ --query "Command.CommandId" \ --output text) # 等待命令执行完成(可根据实际情况调整等待时间) sleep 5 # 获取命令执行结果 aws ssm get-command-invocation \ --command-id $command_id \ --instance-id $instance_id \ --region us-east-1 \ --query "StandardOutputContent" \ --output text
- 要求目标EC2实例已安装SSM Agent(Amazon Linux 2、Amazon Linux 2023默认预装),且实例具备SSM相关IAM权限。
- 可通过轮询
get-command-invocation的Status字段替代固定sleep,确保命令执行完成。
额外优化建议
- 不要在脚本中硬编码
AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY,推荐使用IAM角色、外部传入的环境变量或AWS凭证文件,提升安全性。 - 提取实例ID时,建议添加判断逻辑,避免
jq提取失败导致后续命令报错。
内容的提问来源于stack exchange,提问作者João Carlos
相关产品推荐
相关产品推荐

