我意识到如果您不知道我的集群是如何设置的,这可能很难回答,但我正在尝试将作业(通过 SGE)提交到集群,但环境设置不正确并且作业失败。此外,我可以登录两个不同的主节点以将作业提交到同一集群,并且我的脚本在一个节点上运行,而在另一个节点上不起作用。
这是我的脚本所处理的主节点的机器信息:
cat /proc/version
Linux version 2.6.32-279.el6.x86_64 ([email protected]) (gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) ) #1 SMP Wed Jun 13 18:24:36 EDT 2012
它不工作的机器:
cat /proc/version
Linux version 3.10.0-514.6.2.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) ) #1 SMP Thu Feb 23 03:04:39 UTC 2017
这是我正在使用的测试脚本:
#!/bin/bash -I
#$ -wd ~
#$ -N test
#$ -o ~/test.log
#$ -j y
#$ -terse
#$ -V
#$ -notify
#$ -l h_vmem=2G -pe smp 1 -l athena=true
ls
hostname
nproc
这是运行“qsub test.sh”后的输出:
/bin/bash: module: line 1: syntax error: unexpected end of file
/bin/bash: error importing function definition for `BASH_FUNC_module'
/opt/sge/default/spool/execd/node156/job_scripts/1063646: line 11: ls: command not found
/opt/sge/default/spool/execd/node156/job_scripts/1063646: line 12: hostname: command not found
更令人困惑的是,当我直接 ssh 到这些作业节点(上例中的 node156)时,我可以很好地运行 ls 和主机名命令!
我已经与集群管理员联系,他们无法复制我的问题(即使他们以我的身份登录)。我们首先测试了如果将 ~/.bashrc 和 ~/.bash_profile 设置为默认设置可以修复它,但事实并非如此。以下是这些文件:
cat ~/.bashrc
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
.bash_配置文件:
cat ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
有什么建议么?
答案1
我没有完整的解决方案,因为我对SGE一无所知。但我可以解释部分问题。
脚本运行的计算机正在运行旧版本的操作系统。这不仅可以从内核版本号看出,而且还可以从它已经有一段时间没有收到安全更新的事实中看出。具体来说,我认为它运行的 bash 版本容易受到炮弹休克漏洞。
Bash (ab) 使用环境传递函数。通常,环境仅用于以一系列 形式的项目的形式传递数据。旧版本的 bash 添加以下形式的项目NAME=VALUE
NAME=() {CODE}
,在某些情况下允许通过定义脚本永远不会使用的变量来注入代码 -炮弹休克症。该错误的修复改变了函数编码为.BASH_FUNC_NAME%%=() {CODE}
显然,您的设置的某些部分会转储环境并解析它。这可能是 SGE 的一部分,也可能是您的设置的特定内容。这样做的一个合理的原因是保存提交作业的环境,以便在同一环境中执行作业。
某处正在定义一个module
在 bash 中调用的函数,并将其导出。代码看起来像这样
module () {
…
}
export -f module
修复方法是将环境解析器升级到可以处理新的 bash 编码的版本,或者停止导出函数。