String Bash将以空格分隔的字符串拆分为数量可变的子字符串
假设我的bash脚本中有两个空格分隔的字符串,它们是String Bash将以空格分隔的字符串拆分为数量可变的子字符串,string,bash,String,Bash,假设我的bash脚本中有两个空格分隔的字符串,它们是 permitted_hosts="node1 node2 node3" 及 它们分别表示允许的主机列表和要执行的运行列表。因此,我需要在$allowed\u hosts中的一个主机上运行$runs\u list中的每个运行 我想做的是将$runs\u list划分为$N子字符串,其中$N是$allowed\u hosts中的元素数,其中每个$N子字符串映射到$allowed\u hosts中的不同元素 如果这令人困惑,那么考虑一下具体的解决
permitted_hosts="node1 node2 node3"
及
它们分别表示允许的主机列表和要执行的运行列表。因此,我需要在$allowed\u hosts
中的一个主机上运行$runs\u list
中的每个运行
我想做的是将$runs\u list
划分为$N
子字符串,其中$N
是$allowed\u hosts
中的元素数,其中每个$N
子字符串映射到$allowed\u hosts
中的不同元素
如果这令人困惑,那么考虑一下具体的解决方案。对于上面的$allowed\u hosts
和$runs\u list
的确切给定值,下面的bash脚本将检查当前主机,如果当前主机位于$allowed\u hosts
中,则它将在与当前主机关联的$runs\u list
中启动运行。当然,此脚本不使用变量$allowed\u hosts
和$runs\u list
,但它实现了给定示例所需的效果。我真正想做的是修改下面的代码,这样我就可以修改变量$allowed\u hosts
和$runs\u list
的值,并且它会正常工作
#!/bin/bash
hostname=$(hostname)
if [ "$hostname" == "node1" ]; then
runs="run1 run2"
elif [ "$hostname" == "node2" ]; then
runs="run3 run4"
elif [ "$hostname" == "node3" ]; then
runs="run5"
else
echo "ERROR: Invoked on invalid host ('$hostname')! Aborting."
exit 0
fi
for run in $runs; do
./launch $run
done
因此,首先-您可能应该使用数组,而不是空格分隔的字符串:
permitted_hosts=(node1 node2 node3)
runs_list=(run1 run2 run3 run4 run5)
如果必须从空格分隔的字符串开始,至少可以将它们转换为数组:
permitted_hosts=($permitted_hosts_str)
runs_list=($runs_list_str)
那太离谱了。基本上,您有两个步骤:(1)将主机名转换为一个整数,表示其在允许的\u主机中的位置
:
hostname="$(hostname)"
num_hosts="${#permitted_hosts[@]}" # for convenience
host_index=0
while true ; do
if [[ "${permitted_hosts[host_index]}" = "$hostname" ]] ; then
break
fi
(( ++host_index ))
if (( host_index > num_hosts )) ; then
printf 'ERROR: Invoked on invalid host ('%s')! Aborting.\n' "$hostname" >&2
exit 1
fi
done
# host_index is now an integer index into permitted_hosts
和(2)将该整数转换为运行列表的适当子集:
num_runs="${#runs_list[@]}" # for convenience
for (( run_index = host_index ; run_index < num_runs ; run_index += num_hosts )) ; do
./launch "${runs_list[run_index]}"
done
num#runs=“${#runs#list[@]}”为方便起见
对于((运行索引=主机索引;运行索引
例如,如果您有H个主机,那么主机0将启动run#0、run#H、run#2H等。;主机#1将启动run#1、run#H+1、run#2H+1等。;等等。非常感谢。我知道一定有更好的办法:)
num_runs="${#runs_list[@]}" # for convenience
for (( run_index = host_index ; run_index < num_runs ; run_index += num_hosts )) ; do
./launch "${runs_list[run_index]}"
done