ssh経由のshスタートアップファイル


10

shシェルを開始する前に実行する必要があるいくつかの重要なコマンドがあります。これは、SSHコマンド(ssh host somecommand)およびコマンドを実行する他のプログラムでSSHコマンドを渡すために必要です。

.profileにはこれがあります:

ihammerhands@wreckcreations:~> cat .profile
#specific environment and startup programs
export PS1="\u@wreckcreations:\w> "
export PYTHONPATH=~/python/lib/python2.4/site-packages
export PATH=$PATH:~/bin:~/python/bin

ただし、これは失敗します。

W:\programming\wreckcreations-site\test-hg>ssh name@host echo $PATH
Enter passphrase for key '/home/Owner/.ssh/id_rsa':
/usr/local/bin:/bin:/usr/bin

PATHオプションがないことに注意してください

shプロファイルの適切な名前は何ですか?注:私はrootアクセス権を持っていないので、これを他のユーザーに適用したくありません。これを行う別の方法はありますか?


編集:それは驚くべきことではない/bin/shへのリンクが表示されますbash。驚いたのは、私のプロフィールがまだ無視されていることです。助言がありますか?


1
manページの内容を繰り返すのは嫌なので、「INVOCATION」セクションの下のbash manページを見てください。それは上部にあり、あなたが知る必要があるすべてを説明しています。
camh

を使用してみてくださいssh name@host -t echo $PATH
Gert、

@Gert出力は同じ
TheLQ

@camhマニュアルページをまだチェックしていなかったら、この質問をするでしょうか?私はそれらを何度も読みましたが、他の投稿を読みましたが、どのステージのsshコマンドと他のプログラムのコマンドが実行されるのかがわからないため、この特定の問題に対する答えを見つけることができませんでした
TheLQ

1
@TheLQ:私はあなたを知らないので、manページをチェックするかどうかはわかりません。私が知っていたのは答えがそこにあるということだけだったので、一言一句繰り返すのではなく、私はあなたをそれに向けました。より具体的な指針は、非対話型シェルを検索することです。これは、sshシナリオがそうであるためです。マニュアルページの何かが明確でない場合、おそらくより具体的な質問をすることができます。
camh

回答:


8

質問で言及したコマンドは、

ssh name@host echo $PATH

ほとんど役に立ちません。$ PATHの変数置換はローカルシェルによって行われ、リモートシステムでエコーを実行するsshに渡され、ローカルシステムで展開されたパス変数の内容が出力されます。これが、ネットワーク上のMacとLinuxマシンの間で同様のことをしている例です。

LibMBP:~ will$ echo $PATH
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren echo $PATH
will@warren's password: 
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren 'echo $PATH'
will@warren's password: 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
LibMBP:~ will$ 

ローカルシェルが変数を展開しないように引用符を使用する必要があることに注意してください。


Windows Cygwinランドでは、単一引用符はCygwinまたはコマンドプロンプトで何もしません。奇妙なことに、二重引用符はPATHをCygwinのローカルマシンに完全に拡張します。したがって、sshが提供してくれたものはすべて私のパスではありませんでした。それはサーバーの
問題でした

@TheLQ UNIXプロンプト(Cygwinを含む)では一重引用符が必要ですが、cmdプロンプトでは引用符は必要ありません。
Gilles「SO-邪悪なことをやめる」

12

~/.profileログインシェルによってのみ実行されます。シェルを呼び出すプログラムは、シェルがログインシェルになるかどうかを決定します(-シェル呼び出しの0番目の引数の最初の文字としてa を置くことにより)。通常、ログインして特定のコマンドを実行するときには実行されません。

特にOpenSSHは、コマンドを指定しない場合にのみログインシェルを呼び出します。したがって、コマンドを指定して~/.profileも、読み取られません。

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

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

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

command=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$SHELL\"; fi" ssh-rsa 

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

#!/bin/sh
. ~/.profile
exec "${0##*/}" "$@"

そして、と呼ばれるこのスクリプトへのシンボリックリンクを作るrsyncunisonなど峠、--rsync-path='bin/rsync'上のrsync他のプログラムのためのコマンドラインなど。または、一部のコマンドでは、リモートで実行するシェルスニペット全体を指定できます。これにより、コマンドを自己完結型にすることができます--rsync-path='. ~/.profile; rsync'。たとえば、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

他のコマンドが実行するコマンドについてはどうですか?この場合はMercurialフックになります。Mercurialは、フックが機能することさえ考えるための道にいる必要があります
TheLQ 2010

非対話型のsshコマンドでプロファイルを実行するには、私が示した方法のいずれかを使用します。そのうちの一つ(command=ではauthorized_keys)透過的に動作します。その他の場合は、sshサーバー構成に特定のシェルまたはオプションが必要です。Mercurialと同等のものは--rsync-pathです--remotecmd
Gilles「SO-悪をやめる」


1

通常、ログイン時に、bashは次の場所からコマンドを読み取ります。

〜/ .bash_profile〜
/ .bashrc

bashのmanページから:

〜/ .bash_profile
ログインシェル用に実行される個人用初期化ファイル

〜/ .bashrc
対話型シェルごとの個別の起動ファイル


0

私はこれをテストするために時間を使い果たしましたが、私が見つけたmanページを見ていました:

man bash:bashが非対話的に開始されると、たとえば、シェルスクリプトを実行するために、環境で変数BASH_ENVを探し、そこに表示されている場合はその値を展開し、展開された値をファイルの名前として使用して、読み取りと実行。Bashは、次のコマンドが実行されたかのように動作します。if [-n "$ BASH_ENV"]; その後。"$ BASH_ENV"; fiですが、PATH変数の値はファイル名の検索には使用されません。

man ssh:〜/ .ssh / environment環境変数の追加定義が含まれています。上記の環境を参照してください。

この組み合わせは、sshに.profileを実行させる方法を示唆しています。

残念ながら、私のサーバーではPermitUserEnvironmentがデフォルト値のnoに設定されているため、これは機能しません(私が言ったように、これ以上試す時間はありません)。


環境内のいくつかの環境変数を明示的に指定することでSSHを機能させることができたとしても、他のプログラムがコマンドを呼び出したときにプロファイルが実行されるようにする修正には役立ちません
TheLQ

あなたの例では、あなたがしているすべては環境変数を設定することです、あなたは他に何をしたいですか?
kasterma 2010

0

(削除...新しいユーザーとしてハイパーリンクを1つだけ持つことができます〜)

更新

申し訳ありませんが、これが上記のリンクが適用されない非インタラクティブセッションに関するものであることは知りません。

BashがSH互換モードで起動すると、POSIX®標準にも準拠しながら、shの過去のバージョンの起動時の動作をできるだけ模倣しようとします。ログインシェルの場合、読み込まれるプロファイルファイルは/ etc / profileおよび〜/ .profileです。

ログインシェルでない場合、環境変数ENVが評価され、結果のファイル名が起動ファイルの名前として使用されます。

起動ファイルが読み込まれた後、BashはPOSIX(r)互換モードに入ります(起動ではなく実行用です)。

Bashはsh互換モードで起動します。

  • argv [0]のベースファイル名はshです(:!:uber-clever Linuxユーザーの皆様への注意... / bin / shは/ bin / bashにリンクされている可能性がありますが、/ bin / bashのように機能するわけではありません:!:)

したがって、問題は、シェルがこのように起動されたとしても、なぜそれを実行しないのかということです。

ソース


私は見ましたが、camhに言ったように、どのステージのsshコマンドと他のプログラムコマンドが実行されるのかわかりません。manページと他のガイドをすでに何度も読みました
TheLQ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.