简体   繁体   English

从Shell脚本中的Openstack创建命令的输出获取`id`字段

[英]Get `id` field from output of Openstack creation commands in shell script

OpenStack commands (eg cinder create , nova boot , glance image-create ) output a table of details about the new volume/instance/image. OpenStack命令(例如cinder createnova bootglance image-create )输出有关新卷/实例/映像的详细信息表。

$ cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30
+---------------------+--------------------------------------+
|       Property      |                Value                 |
+---------------------+--------------------------------------+
|     attachments     |                  []                  |
|  availability_zone  |                 nova                 |
|       bootable      |                false                 |
|      created_at     |      2017-01-12T10:58:00.782361      |
| display_description |                 None                 |
|     display_name    |            centos7-cloud             |
|      encrypted      |                False                 |
|          id         | d1c6369b-73ce-498e-a2ef-2c6cea1d0f90 |
|       image_id      | 3896b01c-6afb-41a4-a207-3db87527be2c |
|       metadata      |                  {}                  |
|         size        |                  30                  |
|     snapshot_id     |                 None                 |
|     source_volid    |                 None                 |
|        status       |               creating               |
|     volume_type     |                 None                 |
+---------------------+--------------------------------------+

I am creating a shell script where the next command refers to the new volume by id (in variable CINDER_ID ). 我正在创建一个shell脚本,其中下一个命令通过id (在变量CINDER_ID )引用新卷。

nova boot --block-device source=volume,id=${CINDER_ID},dest=volume centos

What is the best way to extract the id to a variable? id提取到变量的最佳方法是什么?

Following solution using GNU grep which supports look around. 以下使用支持环顾四周的GNU grep解决方案。

grep -owP 'id.*\|\s\K.*[^\|]+' inputfile
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

To storing it to a variable: 要将其存储到变量中:

id=$(grep -owP 'id.*\|\s\K.*[^\|]+' inputfile)

You can try: 你可以试试:

 id=$(cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30 |grep -owP 'id.*\|\s\K.*[^\|]+' )

Using GNU awk's , gensub-function , you can do something like below. 使用GNU awk's gensub-function ,您可以执行以下操作。 The function in the below logic, removes the leading and trailing whitespaces from columns 2,3 field-separated by | 以下逻辑中的函数从由|字段分隔的第2,3列中删除前导和尾随空格|

(checked with writing the table to a file) (已将表写入文件中进行了检查)

awk -F"|" 'gensub(/^[ \t]+|[ \t]+$/,"","g",$2)=="id"{print gensub(/^[ \t]+|[ \t]+$/,"","g",$3);}' file
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

To store it in a variable, 要将其存储在变量中,

idValue="$(awk -F"|" 'gensub(/^[ \t]+|[ \t]+$/,"","g",$2)=="id"{print gensub(/^[ \t]+|[ \t]+$/,"","g",$3);}' file)"
printf "%s\n" "$idValue"
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

You can pipe your command producing the above table to this Awk as 您可以将产生上表的命令通过管道发送给该Awk

<your-command> | awk '{..}'

Something like, 就像是,

cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30 \
       | awk -F"|" 'gensub(/^[ \t]+|[ \t]+$/,"","g",$2)=="id"{print gensub(/^[ \t]+|[ \t]+$/,"","g",$3);}'
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

You can use \\s*\\|\\s* as field separator 您可以使用\\s*\\|\\s*作为字段分隔符

CINDER_ID=$(cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30 |
awk 'BEGIN{FS="\\s*\\|\\s*"}$2=="id"{print $3}')
echo $CINDER_ID

you get 你得到

d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

An alternative that I came up with is the following sed 我想出的一个替代方法是以下sed

sed -n 's/|\s*id\s*|\s*\(.*\S\)\s*|/\1/p' inputfile
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

Storing in a variable, 存储在变量中

CINDER_ID=$(cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c \
--display-name centos7-cloud 30 | sed -n 's/|\s*id\s*|\s*\(.*[^\s]\)\s*|/\1/p' )

echo $CINDER_ID
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

Given that the column values are surrounded by whitespace (in addition to the | column separators), awk 's default field-splitting behavior will do (the | instances then simply count as fields in their own right): 假定列值被空格包围( 除了 |列分隔符), awk的默认字段拆分行为将起作用|实例本身就算作字段):

cinder_ID=$(cinder create ... | awk '$2=="id" {print $4}')

You could append ; exit 你可以追加; exit ; exit inside the block to stop processing right away; 在块内; exit以立即停止处理; probably not worth it for such a small input set, however. 对于这么小的输入集,可能不值得。

Note that I've changed your variable name from CINDER_ID to cinder_ID , because it is better not to use all-uppercase shell-variable names in order to avoid conflicts with environment variables and special shell variables . 请注意,我已将变量名从CINDER_IDcinder_ID ,因为最好不要使用全大写的shell变量名 ,以避免与环境变量和特殊shell变量发生冲突

I think you do not need any Fancy regular expression matchings here. 我认为您在这里不需要任何Fancy正则表达式匹配。 After you create an image with some name , you can this issue this command to get the image id. 创建具有某个名称的图像后,可以发出此命令以获取图像ID。

# openstack image list -f value | grep '<Image name>' | awk '{print $1}'

You can do the same for volume. 您可以对音量执行相同的操作。

# openstack volume list -f value | grep '<volumename>' | awk '{print $1}'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM