我在谷歌云端有一组机器。 来自我的localhost:
function index()
{
$user = $this->session->userdata("id");
$data = $this->customer_model->get_rol_user($user);
foreach ($data as $key=>$value) {
if ($row[$key]->Url === 'customer/index'){
$this->load->view('guest/head');
$this->load->view('guest/nav');
$this->load->view('guest/section');
$this->load->view('customer/customer_view');
}
}
redirect(base_url());
}
我想从第一个命令中获取该列表中的随机工作者名称(比如说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
bash上的一点点弱点。请帮忙
答案 0 :(得分:3)
以下命令从 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 命令输出的随机行。
使用command substitution捕获 gcloud 和 perl 命令的输出,并通过{{3}传递给读取命令}。
我在第一段中引用了 words ,因为shell根据here string(输入字段分隔符)变量将字符序列解释为单词。因此,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'
)
其中<>
读取标题; $.
是保留当前行号的内置变量;其余的来自IFS
。
答案 1 :(得分:2)
gcloud compute instance-groups list-instances workers | grep -v "^NAME" | shuf -n 1 | awk '{print $1, $2}' |
while read machine zone; do
export SELECTED_MACHINE="$machine"
export SELECTED_ZONE="$zone"
done
gcloud compute --project "my-project" ssh --zone "$SELECTED_ZONE" "$SELECTED_MACHINE"
grep -v "^NAME"
剥离以NAME
开头的所有行(假设它只是您要剥离的第一行)shuf
从剩余行中获取随机行awk '{print $1, $2}'
在空格处拆分行并打印第一列和第二列while read
将awk的输出读入变量$machine
和$zone
更新:上面的代码适用于zsh,但不适用于bash,因为bash运行子shell(zsh不会)和export
does only pass variables to subprocesses中的管道,而不是父进程。以下脚本通过在父进程中运行read
来解决此问题:
machine_zone=$(gcloud compute instance-groups list-instances workers |
grep -v "^NAME" | shuf -n 1 | awk '{print $1, $2}')
read machine zone <<< $machine_zone
gcloud compute --project "my-project" ssh --zone "$zone" "$machine"
答案 2 :(得分:2)
如果从中提取随机行的输入很大,并且你想避免将其作为一个整体整体读入内存,那么考虑第二个{{1在Ruslan Osmanov's helpful answer中的解决方案。
否则,hansaplast's helpful answer使用基于shuf
的多实用程序方法,该方法易于理解,但可以简化(并且在撰写本文时,有缺陷):
perl
通过使shuf
读取进程替换(read -r machine zone _ < \
<(gcloud compute instance-groups list-instances workers | tail +2 | shuf -n 1)
gcloud compute --project "my-project" ssh --zone "$zone" "$machine"
)的输出,确保在当前 shell中执行read
,这意味着它创建的变量对其余命令可见,特别是第二次<(...)
调用。
read
),gcloud
在子shell 中执行,则后续命令将无法看到它创建的变量。 gcloud ... | read ...
会跳过输入中的第一行(标题行)。
read
从输入中提取1个随机选择的行。
注意tail +2
作为传递给shuf -n 1
的第3个变量的名称,它接收前2个后输入行的(未使用的) rest 已将空格分隔的标记读入_
和read
。
$machine
和$zone
,则machine
不仅会收到第二个令牌,还会收到输入行的其余部分。