リモートrsyncプロセスの環境変数を設定するにはどうすればよいですか?


12

rsyncを使用して1つのコンピューターから別のコンピューターにファイルをコピーすると、rsyncプロセスが両端で開始されます。ただし、リモートエンドでは、シェル初期化ファイルは明らかに読み取られないため、リモートrsyncプロセスの環境変数を設定できません。残念ながら、rsyncが動作するために環境変数が必要なrsyncを必要とするサーバーが1つあります。私はサーバーの管理者ではないため、グローバル構成を変更できません。リモートrsyncプロセスの環境変数を設定するにはどうすればよいですか?


サーバーでrsyncプロセスをどのように開始しますか?ssh経由でスクリプトをトリガーできますか?
クラフタン

するとrsync localfilename remotehost:remotefilename、サーバーでrsyncプロセスが開始されます。方法は正確にはわかりませんが、シェルの初期化ファイルを読み取りません。
ライアンC.トンプソン

回答:


20

~/.profile通常ssh somecommand、対話型sshセッション(または対話型セッションを開始する他のログイン方法)とは異なり、実行時に読み取られません。

Sshは環境変数の送信をサポートしています。OpenSSHでは、のSendEnvディレクティブを使用し~/.ssh/configます。ただし、サーバー構成のAcceptEnvディレクティブを使用して特定の環境変数を有効にする必要があるため、これがうまく機能しない場合があります。

OpenSSHでは、サーバー側で環境変数を設定することもできます。繰り返しますが、これは、ここではPermitUserEnvironmentディレクティブを使用して、サーバー構成で有効にする必要があります。変数はファイルで設定できます~/.ssh/environment。公開鍵認証を使用すると仮定すると、関連する行の先頭に~/.ssh/authorized_keysadd environment="FOO=bar"でキーごとの変数を設定することもできます。

公開鍵認証を使用している限り、私は常にうまくいくと思う(奇妙なことに)1つのことは、ファイルのオプション(ab)使用するcommand=ことauthorized_keysです。commandオプション付きのキーは、指定されたコマンドを実行する場合にのみ有効です。ただし、authorized_keysファイル内SSH_ORIGINAL_COMMANDのコマンドは、ユーザーが指定したコマンドに設定された環境変数で実行されます(対話型セッションの場合は空です)。そのため、次のようなものを使用できます~/.ssh/authorized_keys(もちろん、このキーを認証に使用しないと適用されません)。

command="export LD_LIBRARY_PATH=\"$HOME\"/lib;
         if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
           eval \"$SSH_ORIGINAL_COMMAND\";
         else exec \"$SHELL\"; fi" ssh-rsa …

読みやすくするために改行を上に置いていますが、実際にはすべてを1行に収める必要があります。

別の可能性は~/bin/rsync-wrapper、サーバー上でラッパースクリプトを記述することです。

#!/bin/sh
. ~/.profile
exec rsync "$@"

次に--rsync-path='bin/rsync-wrapper'rsyncコマンドラインを渡します。への引数--rsync-pathはシェルによって展開されるため、必要に応じてのようなものを渡すことでrsyncコマンドラインを自己完結させることができます--rsync-path='. ~/.profile; rsync'

ログインシェルがbashまたはzshであることに依存する別の方法があります。Bash ~/.bashrcは、rshdまたはsshdによって呼び出されたときに、インタラクティブではない場合でも(ただし、として呼び出された場合ではなく)常に読み取りますsh。Zshは常に読み取ります~/.zshenv

## ~/.bashrc
if [[ $- != *i* ]]; then
  # Either .bashrc was sourced explicitly, or this is an rsh/ssh session.
  . ~/.profile
fi

## ~/.zshenv
if [[ $(ps -p $PPID -o comm=) = [rs]shd && $- != *l* ]]; then
  # Not a login shell, but this is an rsh/ssh session
  . ~/.profile
fi

まあ、それはほとんどそれを要約しています。ラッパースクリプトを使用するよりも良い方法があるといいのですが。
ライアンC.トンプソン

しかし、ちょっと待ってください。シェルの初期化ファイルが読み取られていない場合、どのようにしてサーバー上のrsyncバイナリを見つけることができますか?〜/ usrにインストールしました$PATH。これは、シェルinitスクリプトで追加する必要がある非標準の場所です。
ライアンC.トンプソン

@Ryan:実際には最も直接的な方法を忘れていました(私の編集を参照)が、サーバー構成で有効にするディレクティブも必要です。PATHを考慮する方法を見つけた場合は、そこに他の変数を設定できるはずです。(それでもうまくいかない場合は、set -xシェルスクリプトから始めて、できる限り多くのトレースを追加してください。rsync環境をファイルにダンプし、実際のバイナリを呼び出すラッパースクリプトでバイナリを置き換えます。)
Gilles 'SO -

どう~/.ssh/rc
ライアンC.トンプソン

@Ryan:~/.ssh/rc別のシェルプロセスによって実行されます。あなたの最善の策はラッパースクリプトまたはであると思います--rsync-path='. ~/.profile; rsync'。またはrsync、他の質問に従って適切なrpathで再コンパイルします。
ジル「SO-悪であるのをやめる」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.