web-dev-qa-db-ja.com

sftpを壊さずに.bashrcを使用する

私の問題は、sshシェルにログインするたびにいくつかの変数を設定し、数行を出力する必要があることです。同時に、Filezillaを介してsftpを使用してファイルを転送する必要があります。

Openssh FAQ at http://www.openssh.org/faq.html のように、起動スクリプトが何らかの出力をエコーすると、混乱しますsftpで起動するため、無期限に遅延するか、「サーバーによって終了コード128で接続が閉じられました」というエラーが表示されます。

.bashrcを.bash_profileに移動する、または.bashrcで次のコードを使用するなどの解決策を試しました。

if [ "$TERM" != "dumb" ]
then
   source .bashc_real
fi

そして:

if [ "$TERM" = "xterm" ]
then
   source .bashc_real
fi

ただし、何も機能しません。私のシェルターミナルはbashで、filezillaを使用してsftpに接続します。

20
Joel G Mathew

代わりにこれを試してください

if [ "$SSH_TTY" ]
then
   source .bashc_real
fi
23
Mike

マイクの答えはおそらくうまくいくでしょう。ただし、冗長なものを入れるスタートアップファイルを慎重に選択して、これを達成できることを指摘する価値があります。bashのmanページから:

Bashが対話型ログインシェルとして、または--loginオプションを使用して非対話型シェルとして呼び出されると、ファイル/ etc/profileが存在する場合、そのファイルからコマンドを読み取って実行します。そのファイルを読み取った後、〜/ .bash_profile、〜/ .bash_login、および〜/ .profileをこの順序で検索し、存在し、読み取り可能な最初のコマンドからコマンドを読み取って実行します。シェルの起動時に--noprofileオプションを使用して、この動作を禁止できます。

ログインシェルではないインタラクティブシェルが起動すると、bashは〜/ .bashrcからコマンドを読み取って実行します(そのファイルが存在する場合)。 --norcオプションを使用すると、これを禁止できます。 --rcfile fileオプションは、bashが〜/ .bashrcの代わりにfileからコマンドを読み取って実行するように強制します。

Sftp/scpツールは対話型の非ログインシェルを開始するため、.bashrcがソースになります。多くのディストリビューションは.bash_profileから.bashrcをソースにするか、またはその逆なので、混乱する可能性があります。ログイン環境のクリーン度をテストするための良いトリックは、scp/sftp接続と同じ方法をシミュレートするコマンドでsshを実行することです。例えば: ssh myhost /bin/trueは、scp/sftpが接続したときに表示される内容を正確に示します。

簡単なデモ:

insyte@mazer:~$ echo "echo Hello from .profile" > .profile
insyte@mazer:~$ echo "echo Hello from .bashrc" > .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
Hello from .bashrc
sazerac:~ insyte$

insyte@mazer:~$ rm .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
sazerac:~ insyte$

最初のテストはscp/sftp/rsyncなどを壊します。 2番目のバージョンは問題なく動作します。

17
Insyte

Cshを使用している場合:

if ($?prompt)
  ... interactive stuff ...

そしてそれがbashの場合:

if [[ $- == *i* ]]; then
  ... interactive stuff ...
fi

または、bash正規表現を使用する:

if [[ $- =~ i ]]; then
  ... interactive stuff ...
fi

これらの行は、何かを出力/エコーする行の前に置く必要があります。

3
user163384

マイクの解決策も私にとってうまくいきました。しかし、私のデフォルトのシェルはTCSHなので、次のように(.tcshrcで)修正を少し編集する必要がありました。

if ( $?SSH_TTY ) then
    exec /bin/bash
endif

みんなの利益のために私が分かち合うと思いました。

1
Vijay Padiyar

私はここで述べた他の解決策をいくつか気に入っていますが、誰かが役立つ情報を見つけた場合に備えて、起動スクリプトのエコーコマンドによるSFTP切断を防ぐために、現在bashおよびcsh VMで使用している解決策を捨てると思いました。

BASHの場合:

if [ $TERM == "xterm" ] || [ $TERM == "xterm-256color" ]; then
  echo "Xterm display identified: echo enabled"
  echo_disable="0"
else
  echo_disable="1"
fi

# Use the following for all subsequent echo commands
if [ $echo_disable == 0 ]; then
 echo "Safe to display on Xterm"
fi

Cshでは:

if ($TERM == "xterm") then
  echo "Xterm display identified: echo enabled"
  set echo_disable = "0"
else
  set echo_disable = "1"
endif

# Use the following for all subsequent echo commands
if !( "$echo_disable" ) echo "Safe to display on Xterm"

少し力ずくで動作しますが、機能します。

0
Bob Noonan

これが私の最初の行です(デフォルト).bashrcファイル:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

インタラクティブセッションのチェックにより、SCP、SFTP、またはssh remote-Host commandモード。

これがなければ、ファイル.bashrcechoを使用するか、stdoutで他の印刷を使用します。次のようなエラーが発生する可能性があります。

  • SFTP:Received message too long 168435779
  • SCP:protocol error: unexpected <newline>
0
Totor