heredoc 和 PBS 的数组索引问题
Array indexing problems with heredoc and PBS
我正在编写一个脚本,该脚本生成由 PBS 调度系统 运行 的批处理作业,使用 heredoc 创建作业实例。问题是,批处理脚本中的数组不能被变量索引。它总是 returns 数组的第一个元素。相比之下,按整数索引数组会按预期工作。
#!/bin/bash
export MY_ARRAY=(a b c)
export MY_ARRAY_LENGTH=${#MY_ARRAY[@]}
qsub -V -lselect=1:ncpus=1:mem=8gb -lwalltime=00:01:00 -N test -J 1-${MY_ARRAY_LENGTH} <<EOF
echo "PBS array index: $PBS_ARRAY_INDEX"
I=$((${PBS_ARRAY_INDEX} - 1))
echo "MY_ARRAY index: $I"
## this works as expected, returning the second element of the array
echo "element selected by integer: ${MY_ARRAY[1]}"
## this does not work as expected, returning the first element of
## MY_ARRAY regardles of $I
echo "element selected by variable: ${MY_ARRAY[$I]}"
EOF
数组作业 3 的输出,即第 3 个元素是:
PBS array index: 3
MY_ARRAY index: 2
element selected by integer: b
element selected by variable: a
在上面的例子中,表达式 ${MY_ARRAY[$I]} 应该给我
值“c”。为什么这不起作用?
注意我明白转义符号\
是变量所必需的
不被调用脚本评估,但这似乎并不
所有变量都是这种情况。这是为什么?
编写此类脚本非常困难,double-escaping 令人困惑。考虑一个不同的方法,它只是将上下文发送到远程端 包括要执行的代码 然后执行代码。这样代码就简单了。记得用 shellcheck 检查你的脚本。
#!/bin/bash
MY_ARRAY=(a b c)
work() {
# normal script
echo "PBS array index: $PBS_ARRAY_INDEX"
I=$((${PBS_ARRAY_INDEX} - 1))
echo "MY_ARRAY index: $I"
## this works as expected, returning the second element of the array
echo "element selected by integer: ${MY_ARRAY[1]}"
## this does not work as expected, returning the first element of
## MY_ARRAY regardles of $I
echo "element selected by variable: ${MY_ARRAY[$I]}"
}
qsub -V -lselect=1:ncpus=1:mem=8gb -lwalltime=00:01:00 -N test -J 1-${MY_ARRAY_LENGTH} <<EOF
$(declare -p MY_ARRAY) # serialize variables
$(declare -f work) # serialize function
work # excute the function
EOF
## this does not work as expected, returning the first element of
## MY_ARRAY regardles of $I
是,I=
在 远程端 设置,而 ${MY_ARRAY[$I]}
在 客户端 扩展.客户端没有设置I
,所以$I
为空,空转为0
,成为第一个元素
我正在编写一个脚本,该脚本生成由 PBS 调度系统 运行 的批处理作业,使用 heredoc 创建作业实例。问题是,批处理脚本中的数组不能被变量索引。它总是 returns 数组的第一个元素。相比之下,按整数索引数组会按预期工作。
#!/bin/bash
export MY_ARRAY=(a b c)
export MY_ARRAY_LENGTH=${#MY_ARRAY[@]}
qsub -V -lselect=1:ncpus=1:mem=8gb -lwalltime=00:01:00 -N test -J 1-${MY_ARRAY_LENGTH} <<EOF
echo "PBS array index: $PBS_ARRAY_INDEX"
I=$((${PBS_ARRAY_INDEX} - 1))
echo "MY_ARRAY index: $I"
## this works as expected, returning the second element of the array
echo "element selected by integer: ${MY_ARRAY[1]}"
## this does not work as expected, returning the first element of
## MY_ARRAY regardles of $I
echo "element selected by variable: ${MY_ARRAY[$I]}"
EOF
数组作业 3 的输出,即第 3 个元素是:
PBS array index: 3
MY_ARRAY index: 2
element selected by integer: b
element selected by variable: a
在上面的例子中,表达式 ${MY_ARRAY[$I]} 应该给我 值“c”。为什么这不起作用?
注意我明白转义符号\
是变量所必需的
不被调用脚本评估,但这似乎并不
所有变量都是这种情况。这是为什么?
编写此类脚本非常困难,double-escaping 令人困惑。考虑一个不同的方法,它只是将上下文发送到远程端 包括要执行的代码 然后执行代码。这样代码就简单了。记得用 shellcheck 检查你的脚本。
#!/bin/bash
MY_ARRAY=(a b c)
work() {
# normal script
echo "PBS array index: $PBS_ARRAY_INDEX"
I=$((${PBS_ARRAY_INDEX} - 1))
echo "MY_ARRAY index: $I"
## this works as expected, returning the second element of the array
echo "element selected by integer: ${MY_ARRAY[1]}"
## this does not work as expected, returning the first element of
## MY_ARRAY regardles of $I
echo "element selected by variable: ${MY_ARRAY[$I]}"
}
qsub -V -lselect=1:ncpus=1:mem=8gb -lwalltime=00:01:00 -N test -J 1-${MY_ARRAY_LENGTH} <<EOF
$(declare -p MY_ARRAY) # serialize variables
$(declare -f work) # serialize function
work # excute the function
EOF
## this does not work as expected, returning the first element of ## MY_ARRAY regardles of $I
是,I=
在 远程端 设置,而 ${MY_ARRAY[$I]}
在 客户端 扩展.客户端没有设置I
,所以$I
为空,空转为0
,成为第一个元素