Bash 获取使用ec2 api工具新启动的实例的ID

Bash 获取使用ec2 api工具新启动的实例的ID,bash,scripting,awk,amazon-ec2,ec2-api-tools,Bash,Scripting,Awk,Amazon Ec2,Ec2 Api Tools,我通过从简单的bash脚本调用来启动一个EC2实例,并希望在该实例上执行进一步的操作(例如,关联弹性IP),我需要实例id 该命令类似于ec2运行实例ami-dd8ea5a9-K pk.pem-C cert.pem--region eu-west-1-t c1.medium-n1,其输出: RESERVATION r-b6ea58c1 696664755663 default INSTANCE i-945af9e3 ami-dd8ea5b9 pending 0

我通过从简单的bash脚本调用来启动一个EC2实例,并希望在该实例上执行进一步的操作(例如,关联弹性IP),我需要实例id

该命令类似于
ec2运行实例ami-dd8ea5a9-K pk.pem-C cert.pem--region eu-west-1-t c1.medium-n1
,其输出:

RESERVATION r-b6ea58c1    696664755663    default
INSTANCE    i-945af9e3    ami-dd8ea5b9    pending    0    c1.medium    2010-04-15T10:47:56+0000    eu-west-1a    aki-b02a01c4    ari-39c2e94d   
在本例中,
i-945af9e3
是我要查找的id


因此,我需要一种简单的方法来解析命令返回的id—您将如何进行?我的AWK有点生锈了。。。您可以随意使用典型Linux设备上提供的任何工具。(如果有一种方法可以直接使用EC2 API工具获取它,那就更好了。但是afaik没有EC2命令,例如,返回最近启动的实例的id。)

好的,至少类似的方法应该可以工作:

instance_id=$(ec2-run-instances ami-dd8ea5a9 [...] | awk '/INSTANCE/{print $2}') 
诚然,我有点懒,认为继续问比重新学习一些AWK基础知识更快…:-)


编辑:丹尼斯建议的简化AWK用法。此外,为了清晰起见,使用
$()
代替``并去掉中间变量

完成正确答案后,下面是一个shell脚本,它创建一个实例,运行一些命令并删除该实例。它使用awk的方式与您的方式相同

#!/bin/sh

# Creates an Amazon EC2 virtual machine (an instance) and runs some
# shell commands on it before terminating it. Just an example.
# Stephane Bortzmeyer <stephane+amazon@bortzmeyer.org>

# Parameters you can set.
# Choose an AMI you like (ami-02103876 is a Debian "lenny")
AMI=ami-02103876
# Create your key pair first, for instance on the Web interface
KEY=test-b
KEYDIR=.
# The user name to use depends on the AMI. "root" is common but check
# the documentation of the AMI.
USERNAME=root
# Needs to be a legal Unix group of commands
COMMANDS="(uname -a; df -h; cat /etc/debian_version)"
MAX_CONNECTS=4
MAX_TESTS=6

# If you want to change from the default region, set the environment
# variable EC2_URL for instance 'export
# EC2_URL=https://ec2.eu-west-1.amazonaws.com' to use the 'eu-west-1'
# region

# Also, be sure your default security group allows incoming SSH.

if [ "${EC2_PRIVATE_KEY}" = "" ] || [ "${EC2_CERT}" = "" ]; then
    echo "You need to have X.509 certificate and private key locally, and to set the environment variables EC2_PRIVATE_KEY and EC2_CERT to indicate their locations" 1>&2
    exit 1
fi

start=$(ec2-run-instances --key ${KEY} $AMI)
if [ $? != 0 ]; then
    echo "Machine did not start" 1>&2
    exit 1
fi

AMI_E=$(echo "$start" | awk '/^INSTANCE/ {print $3}')
if [ "$AMI_E" != "$AMI" ]; then
    echo "AMI does not match (got $AMI_E instead of $AMI), the machine probably did not start" 1>&2
    exit 1
fi
INSTANCE=$(echo "$start" | awk '/^INSTANCE/ {print $2}')

# I do not find a way to block until the machine is ready. We

# apparently have to poll.
OVER=0
TESTS=0
while [ $OVER != 1 ] && [ $TESTS -lt $MAX_TESTS ]; do
    description=$(ec2-describe-instances ${INSTANCE})
    STATE=$(echo "$description" | awk '/^INSTANCE/ {print $6}')
    NAME=$(echo "$description" | awk '/^INSTANCE/ {print $4}')
    if [ "$NAME" = "" ]; then
        echo "No instance ${INSTANCE} available. Crashed or was terminated." 1>&2
        exit 1
    fi
    if [ $STATE = "running" ]; then
        OVER=1
    else
        # I like bc but 'echo $(( TESTS+=1 ))' should work, too. Or expr.
        TESTS=$(echo $TESTS+1 | bc)
        sleep 2
    fi
done
if [ $TESTS = $MAX_TESTS ]; then
    echo "${INSTANCE} never got to running state" 1>&2
    ec2-terminate-instances ${INSTANCE}
    exit 1
fi
echo "$INSTANCE is running, name is $NAME"
# The SSH server does not seem reachable immediately. We again have to poll
OVER=0
TESTS=0
while [ $OVER != 1 ] && [ $TESTS -lt $MAX_CONNECTS ]; do
    ssh -o "StrictHostKeyChecking no" -i ${KEYDIR}/${KEY}.pem ${USERNAME}@$NAME "${COMMANDS}"
    if [ $? != 255 ]; then
        # It means we connected successfully (even if the remote command failed)
        OVER=1
    else
        TESTS=$(echo $TESTS+1 | bc)
        sleep 3
    fi
done
if [ $TESTS = $MAX_CONNECTS ]; then
    echo "Cannot connect to ${NAME}" 1>&2
fi
ec2-terminate-instances ${INSTANCE}
#/垃圾箱/垃圾箱
#创建一个AmazonEC2虚拟机(一个实例)并运行一些
#在终止之前,在其上执行shell命令。只是一个例子。
#斯蒂芬·博茨梅尔
#可以设置的参数。
#选择您喜欢的AMI(AMI-02103876是Debian“lenny”)
AMI=AMI-02103876
#首先创建密钥对,例如在Web界面上
键=测试b
KEYDIR=。
#要使用的用户名取决于AMI。“根”是常见的,但请检查
#AMI的文档。
用户名=根
#必须是合法的Unix命令组
COMMANDS=“(uname-a;df-h;cat/etc/debian_版本)”
最大连接数=4
最大测试=6
#如果要更改默认区域,请设置环境
#实例“导出”的变量EC2_URL
#EC2_URL=https://ec2.eu-west-1.amazonaws.com使用“eu-west-1”
#区域
#另外,确保默认安全组允许传入SSH。
如果[“${EC2_PRIVATE_KEY}”=”]| |[“${EC2_CERT}”=”];然后
echo“您需要本地拥有X.509证书和私钥,并设置环境变量EC2_private_key和EC2_CERT以指示其位置”1>&2
出口1
fi
start=$(ec2运行实例--key${key}$AMI)
如果[$?!=0];然后
echo“机器未启动”1>&2
出口1
fi
AMI_E=$(echo“$start”| awk'/^INSTANCE/{print$3}')
如果[“$AMI_E”!=“$AMI”];然后
echo“AMI不匹配(得到$AMI\E而不是$AMI),机器可能没有启动”1>&2
出口1
fi
实例=$(回显“$start”| awk'/^INSTANCE/{print$2}”)
#在机器准备好之前,我找不到阻止的方法。我们
#显然,我必须投票。
超过=0
测试=0
而[$OVER!=1]&&&[$TESTS-lt$MAX_TESTS];做
description=$(ec2描述实例${INSTANCE})
状态=$(回显“$description”| awk'/^INSTANCE/{print$6}”)
名称=$(回显“$description”| awk'/^INSTANCE/{print$4}”)
如果[“$NAME”=”;然后
echo“没有可用的实例${instance}。崩溃或被终止。”1>&2
出口1
fi
如果[$STATE=“running”];然后
超过=1
其他的
#我喜欢bc,但“echo$((TESTS+=1))”也应该有效。或expr。
测试=$(echo$测试+1 | bc)
睡眠2
fi
完成
如果[$TESTS=$MAX_TESTS];然后
echo“${INSTANCE}从未达到运行状态”1>&2
ec2终止实例${INSTANCE}
出口1
fi
echo“$实例正在运行,名称为$name”
#SSH服务器似乎无法立即访问。我们又要投票了
超过=0
测试=0
而[$OVER!=1]&&&[$TESTS-lt$MAX_CONNECTS];做
ssh-o“StrictHostKeyChecking no”-i${KEYDIR}/${KEY}.pem${USERNAME}@$NAME“${COMMANDS}”
如果[$?!=255];然后
#这意味着我们成功连接(即使远程命令失败)
超过=1
其他的
测试=$(echo$测试+1 | bc)
睡眠3
fi
完成
如果[$TESTS=$MAX_CONNECTS];然后
echo“无法连接到${NAME}”1>&2
fi
ec2终止实例${INSTANCE}
无需使用awk:

# create the instance and capture the instance id
echo "Launching instance..."
instanceid=$(ec2-run-instances --key $pemkeypair --availability-zone $avzone $ami | egrep ^INSTANCE | cut -f2)
if [ -z "$instanceid" ]; then
    echo "ERROR: could not create instance";
    exit;
else
    echo "Launched with instanceid=$instanceid"
fi

作为ec2运行实例的替代方案,您可以创建一个ec2实例并通过awscli获取一行InstanceId:


不需要grep:`awk'/INSTANCE/{print$2}'谢谢@Dennis-现在有点干净了,我无法让你的awk在ubuntubash中工作。实例_id=$((ec2运行实例ami-2b0b1442-O aws访问密钥id-W aws秘密访问密钥-k my key-g default-t m1.small | awk'/instance/{print$2}')|awk'/instance/{prin$2}');echo$instance\u id>>~/instance\u id.txt我看到打印错误,编辑超时,无法完成。还发现评论中不允许使用任何键。当我从下面替换“egrep和cut”命令时,它起到了作用。欢迎链接到潜在的解决方案,但请确保您的其他用户能够了解它是什么以及为什么存在。始终引用重要链接中最相关的部分,以防无法访问目标站点或永久脱机。考虑到仅仅是一个到外部站点的链接是一个可能的原因。#获取实例id cat sample.json | jq'.Instances[0]。InstanceId'| sed-e's/^”/'-e's/“$/”#检查实例是否正在运行cat status.json | jq'.instancestatus[0]。InstanceState.Name'| sed-e's/^/'-e's/“$/'若要运行上述命令,请安装jq,然后将json响应保存在文件中,然后重试..我的回答上面已经共享了jq的安装链接。请在回答时提供此信息,而不是发表评论。
http://www.tothenew.com/blog/how-to-parse-json-by-command-line-in-linux/
best tool to parse json in shell

#get instance id 
cat sample.json | jq '.Instances[0].InstanceId'|sed -e 's/^"//' -e 's/"$//' 
#check instances is running or not 
cat status.json | jq '.InstanceStatuses[0].InstanceState.Name'|sed -e 's/^"//' -e 's/"$//' 
export MyServerID=$(aws ec2 run-instances --image-id AMI --count 1 --instance-type t2.micro --key-name "my_ssh_key" --security-group-ids sg-xxx --subnet-id subnet-yyy --query 'Instances[0].InstanceId' --output text)