我意識到如果您不知道我的集群是如何設定的,這可能很難回答,但我正在嘗試將作業(透過 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 編碼的版本,或停止匯出函數。