团队,我有一组在此脚本 A 中定义的参数,它们的默认值为“DEFAULT”。当用户将这些变量参数设置为“DEFAULT”以外的任何值时,我必须运行另一个具有更新变量值的脚本,否则我将运行另一个具有默认值的脚本-B。所以,我有三种情况
我在脚本中模拟詹金斯参数设置。默认值是在设置为环境变量的 jenkins 作业上预设的,然后运行此脚本。因此,如果用户不更改任何参数并将所有 fio_gen 的值设置为默认值,那么它们将被我在脚本中定义的值替换。
1-Run Script-B with DEFAULT variable values
2-Run Script-B with all-non-DEFAULT variable values
3-Run Script-B with mixed variable values.. some default and some non.
我的代码在下面,它确定哪些变量是默认变量而不是默认变量,但我想不出为上面的混合做 case-3 的逻辑。
我应该在 vars_ioengine_defaults 中使用关联数组并进行比较和使用吗?或者什么是好的方法?
#!/bin/bash
declare -a vars=(IOEngine TestType Threads BlockSize FileSize DatasetSize QueueDepth RunTime UDCName)
for var_name in "${vars[@]}"
do
if [ -z "${!var_name}" ]; then
echo "Missing environment variable $var_name"
exit 1
fi
done
#***Comment unComment to test 3 cases"
#DatasetSize="DEFAULT"
#BlockSize="DEFAULT"
#DatasetSize="nonDEFAULT"
#BlockSize="nonDEFAULT"
DatasetSize="DEFAULT"
BlockSize="NON-DEFAULT"
preset="DEFAULT"
declare -a dynamic_vars=( DatasetSize BlockSize )
number_of_dynamic_vars="${#dynamic_vars[@]}"
number_of_default_values=0
overwrite_all() {
printf "all non-defaults variables\n"
fio_gen
}
overwrite_some() {
printf "some defaults variables\n"
for [[ "${!var}" == "$preset" ]]
do
# SOME LOGIC HERE TO replace non-default and call this function
fio_gen
done
}
overwrite_none() {
printf " all defaults variables\n"
vars_ioengine_defaults
fio_gen
}
check_vars() {
for var in "${dynamic_vars[@]}"
do
[[ "${!var}" == "$preset" ]] && ((number_of_default_values++))
done
if [[ "$number_of_default_values" -eq 0 ]]; then
echo "None var is default"
overwrite_all
elif [[ "$number_of_default_values" -eq "$number_of_dynamic_vars" ]]; then
echo "All defaults"
overwrite_none
else
echo "Mixed"
overwrite_some
echo $var
fi
}
vars_ioengine_defaults() {
RunTime="0"
UDCNAme="stage"
if [[ "$IOEnginge" == "psync" ]] && [[ "$TestType" == "read" ]]; then
QueueDepth="0"
DatasetSize="3G"
BlockSize="2,4,8,16,32,64,128,256,512,1024"
Threads="1,2,4,8,16,32,64,128,256"
FileSize="3M"
elif [[ "$IOEngine" == "psync" ]] && [[ "$TestType" == "randread" ]]; then
QueueDepth="0"
DatasetSize="1G"
BlockSize="8,16,32"
Threads="16,32,64,128,256"
FileSize="32k"
elif [[ "$IOEngine" == "libaio" ]] && [[ "$TestType" == "read" ]]; then
QueueDepth="16"
DatasetSize="3G"
BlockSize="2,4,8,16,32,64,128,256,512,1024"
Threads="1,2,4,8,16,32,64,128,256"
FileSize="3M"
elif [[ "$IOEngine" == "libaio" ]] && [[ "$TestType" == "randread" ]]; then
QueueDepth="16"
DatasetSize="1G"
BlockSize="8,16,32"
Threads="16,32,64,128,256"
FileSize="32k"
fi
}
fio_gen() {
echo "iteratre on -p $IOEngine -t $TestType -j $Threads -b $BlockSize -s $FileSize -d $DatasetSize -q $QueueDepth -r $RunTime -u $UDCName"
}
check_vars
如果问题是为 bash 脚本提供默认参数,那么我们的姊妹站点 Stack Overflow 上的帖子可以解决这个问题。
如果参数是位置参数,您会在 如何编写采用可选输入参数的 bash 脚本?.
这些解决方案使用Bash Reference Manual - 3.5.3 Shell Parameter Expansion中定义的 参数扩展,尤其是像
${1:-foo}
.例如,您可以在脚本中包含:
上面的脚本要求缺少的参数始终是最后一个。
如果您更愿意在脚本中使用命名参数,一些方法在将 命名参数传递给 shell 脚本一文中有所描述。
对于帖子中的一个示例,如果您使用单字母参数,例如在 calling 中
my_script -p '/some/path' -a5
,您可以使用类似的代码来:这是实现以下过程的解决方案的存根:
DFLT_
源配置文件,其中所有默认值都在以前缀命名的变量中定义。例如DFLT_BlockSize
定义默认值BlockSize
。DFLT_
)...DEFAULT
,则将其替换为默认变量的值。让它成为我们的
config.defaults
:这是脚本:
解释:
"${!DFLT_@}"
返回以 开头的所有变量的名称DFLT_
。在循环的每次迭代中for
扩展$dvar
到下一个这样的名称,例如DFLT_BlockSize
。"${dvar#DFLT_}"
删除"$dvar"
了前导。DFLT_
例如,如果$dvar
扩展到DFLT_BlockSize
然后${dvar#DFLT_}
扩展到BlockSize
。这存储为var
.declare -n var
对 的值引用的变量执行所有引用、赋值和属性修改var
(使用或更改属性本身的除外) 。在我们的示例中(用于扩展到)从现在开始表现得像并且表现得像。-n
var
$var
BlockSize
$var
$BlockSize
var=
BlockSize=
${!dvar}
是类似的东西,没有declare -n
: if$dvar
expands toDFLT_BlockSize
then${!dvar}
behaves like$DFLT_BlockSize
。(如果我们这样做declare -n dvar
,我们只$dvar
需要获得相同的效果)。所以当
$dvar
扩展到时DFLT_BlockSize
,该行表现得像
我们需要
declare +n var
(+n
revokes-n
) 以便var="${dvar#DFLT_}"
在下一个循环中更改var
,而不是BlockSize
。笔记:
DFLT_
您可以直接在脚本中定义这些变量(而不是. "/path/to/config.defaults"
)。config.defaults
是 source,您应该将其视为脚本的一部分。特别是它绝不仅限于设置变量;您放入此文件中的任何代码都将被执行,就好像它在脚本本身中一样。但这也意味着您可以在配置文件中添加注释;或条件语句!(以防万一:foo=bar rm -rf /precious/data
会运行rm
!foo="bar rm -rf /precious/data"
不会)。local DFLT_foo=bar
. 我决定保持示例文件简单,但local
看起来合理。DFLT_1
to affect$1
会导致错误,因为位置参数的行为与常规变量有些不同。