4

特定のタスクを別のユーザーが所有する他の特定のbashスクリプトに委任するbashバックアップスクリプトをroot(cron)として実行しています。(簡略化された例、原則として、rootとして実行する必要があるものがあり、さまざまなタスクが適切な環境(oracle、amazon、...)を持つユーザーに委任されます。

mkdir -p /tmp/backup$NAME
su - oracle -c "~/.backups/export-test.sh"
tar cf /tmp/backup/$NOW.tar /tmp/backup$NAME
su - amazon upload_to_amazon.sh /tmp/backup/$NOW.tar

このスクリプト自体は、ユーザーoracleとしていくつかのタスクを実行します。

mkdir -p $TMP_LOCATION
cd ~/.backups
exp $TMP_LOCATION/$NAME-$NOW

Pythonでこの動作を模倣しようとすると、次のことがわかりました(ルートとしてcronから開始)

name = "oracle"

# part run as root
os.makedirs(tmp_backup + name)


os.setegid(pwd.getpwnam(name)[3])
os.seteuid(pwd.getpwnam(name)[2])

# part run as oracle
os.makedirs(tmp_location)
os.chdir(os.path.expanduser("~{user}/.backups".format(user=name)))
subprocess.check_call(["exp",
                       "os.path.join(tmp_location, name+'-'+now)"
                      ])

su-を使用する場合のbashでは、実際の新しいシェルが呼び出され、そのユーザーのすべての環境変数が設定されます。Pythonスクリプトでこれをどのように改善できますか?私が従うことができる標準的なレシピはありますか?私は環境変数、umask、...を考えています。

それが問題になる可能性がある場合、環境はSolarisです。

4

2 に答える 2

1

そのユーザーのすべての環境変数が設定されている

通常、シェルは.profile起動時にファイルを実行するためです。

いくつかの選択肢があります。

  1. subprocess.Popenでシェルを実行するための適切なサブプロセスを作成します.profile- と同じsu -です。

  2. 環境変数の設定を慎重に見つけて、Python で模倣します。問題は、.profileがあらゆる種類のクレイジーなことを実行できるため、 の正確な効果を判断することが潜在的な問題になること.profileです。

  3. または、関連する環境変数を抽出して、シェル環境と Python プログラムの両方からアクセスできるようにすることもできます。

初め。for each user を読んで、.profile設定する環境変数を明確にしてください (Python スクリプトに適用されないエイリアスやその他のクレイジーなものとは異なります)。これらの環境変数の一部は、実行中のスクリプトに関連しています。一部は関係ありません。

2番。「関連する」環境変数をきちんとしたenv_backups.shスクリプトまたはenv_uploads.shスクリプトに分割します。

これらの環境変数スクリプトを作成したら、ファイルを更新して、環境変数の設定をまたは.profileに置き換えます。source env_backup.shsource env_uploads.sh

三番。Python プログラムを実行する前に、関連するスクリプトを入手しますenv_thisenv_thatこれで、Python 環境は変数をシェル環境と共有し、それらを 1 か所で管理するだけですみます。

my_script.sh

source ~oracle/env_backup.sh
source ~amazon/env_uploads.sh
python my_script.py

それが一番いいように思えます。(それが私たちのやり方だからです。)

于 2010-08-20T10:26:24.497 に答える
0

結局、環境変数を必要とせずに、ルートとして amazon を実行できます。そのためにbotoを使用しました。

Oracle 環境変数については、次のコードを使用しました。

if "ORACLE_HOME" not in os.environ or os.environ["ORACLE_HOME"] != ORACLE_HOME:
    logger.debug("setting ORACLE_HOME='{oh}'".format(oh=ORACLE_HOME))
    os.environ['ORACLE_HOME'] = ORACLE_HOME
if ORACLE_HOME + "/bin" not in os.environ["PATH"].split(":"):
    logger.debug("setting PATH='{p}'".format(p=os.path.expandvars(ORACLE_PATH)))
    os.environ['PATH'] = os.path.expandvars(ORACLE_PATH)
if "NLS_LANG" not in os.environ or os.environ["NLS_LANG"] != NLS_LANG:
    logger.debug("setting NLS_LANG='{n}'".format(n=NLS_LANG))
    os.environ['NLS_LANG'] = NLS_LANG
于 2011-12-02T08:10:19.793 に答える