我在谷歌云有一组机器。 来 self 的本地主机:
gcloud compute instance-groups list-instances workers
OUTPUT:
NAME ZONE STATUS
workers-lya2 us-central1-a RUNNING
workers-23d4 us-central1-a RUNNING
...
workers-3asd3 us-central1-a RUNNING
我想要一个来自该列表的随机工作人员名称(比如 workers-23d4
),它是来自第一个命令的区域 us-central1-m
并将其粘贴到此命令:
gcloud compute --project "my-project" ssh --zone "<zone_name_from_first_command> "<machine_name_from_first_command>"
bash 有点弱。请帮忙
最佳答案
以下命令从 gcloud 命令的输出中随机选择一行(不包括标题),然后将前两个“单词”存储到 machine
中和 zone
变量:
read -r machine zone unused <<< $(
gcloud compute instance-groups list-instances workers | \
perl -e '@_ = <>; shift @_; print $_[rand @_]'
)
执行此命令后,您就可以使用 machine
和 zone
变量,例如:
gcloud compute --project "my-project" ssh --zone "$zone" "$machine"
解释
perl 命令从标准输入中读取所有行到 @_
使用菱形运算符的数组 <>
.那么 shift
函数从 @_
中删除第一项. rand
@_
返回一个介于零和 @_
中的项目数之间的随机十进制数.十进制数在索引上下文中隐式转换为整数。因此,$_[rand @_]
的结果是@_
的随机元素,即 gcloud 命令输出的随机行。
gcloud 和 perl 命令的输出是使用 command substitution 捕获的并通过 here string 传递给 read 命令.
我在第一段中引用了 words,因为 shell 根据 IFS
将字符序列解释为单词。 (输入字段分隔符)变量。所以 IFS
- 此处字符串中的分隔词分配给 machine
(第一个字),zone
(第二个字)和unused
(该行的其余部分)变量。
-r
选项禁用反斜杠的特殊含义。换句话说,当给出此选项时,read 将不会尝试解释输入中的转义序列。
大行数情况
请注意,该解决方案意味着 gcloud 命令的输出相对较小,即小到足以将整个文件压缩到一个数组中。此操作速度很快,但与使用 while <>
逐行读取相比需要更多内存环形。如果输出非常大,或者内存非常有限,这是另一种解决方案:
read -r machine zone unused <<< $(
gcloud compute instance-groups list-instances workers | \
perl -e '<>; $. = 0; rand($.) < 1 && ($line = $_) while <>; print $line'
)
哪里<>
读取标题; $.
是保持当前行号的内置变量;其余部分取自 this cookbook .
关于linux - 使用另一个 bash 命令输出的 bash 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41791386/