クラスターの設定方法がわからないと答えるのが難しいかもしれませんが、クラスターにジョブ (SGE 経由) を送信しようとしていますが、環境が正しく設定されていないためジョブが失敗します。さらに、同じクラスターにジョブを送信するためにログインできる 2 つの異なるマスター ノードがあり、スクリプトは一方には機能しますが、もう一方には機能しません。
これは、私のスクリプトが動作するマスター ノードのマシン情報です。
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
さらに混乱を招くのは、これらのジョブ ノード (上記の例では node156) に直接 ssh すると、ls コマンドと hostname コマンドを問題なく実行できることです。
クラスター管理者に連絡しましたが、私の問題を再現できませんでした (私としてログインしても)。まず、~/.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は(悪用)環境関数を渡すために環境を使用します。通常、環境は、一連の形式の項目の形でデータを渡すためにのみ使用されます。古いバージョンのbashでは、形式の項目が追加され、スクリプトが決して使用しない変数を定義することでコードを挿入できる場合がありました。NAME=VALUE
NAME=() {CODE}
シェルショックバグバグの修正により、関数を にエンコードする方法が変更されました。BASH_FUNC_NAME%%=() {CODE}
明らかに、セットアップの一部が環境をダンプして解析しています。これは SGE の一部であるか、セットアップに固有のものである可能性があります。これを行うもっともらしい理由は、ジョブが送信された環境を保存し、同じ環境でジョブを実行することです。
どこかでbashで呼び出される関数を定義しmodule
、それをエクスポートしています。コードは次のようになります。
module () {
…
}
export -f module
修正するには、環境パーサーを新しい bash エンコーディングに対応できるものにアップグレードするか、関数のエクスポートを停止します。