sftpを中断せずに.bashrcを使用する


20

私の問題は、sshシェルにログインするたびにいくつかの変数を設定し、数行を出力する必要があり、同時にFilezilla経由でファイルをtarnsferできるようにする必要があることです。

現在、https //www.openssh.org/faq.htmlのopenssh FAQにあるように、スタートアップスクリプトがあらゆる種類の出力をエコーする場合、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に接続します。

回答:


23

代わりにこれをやってみてください

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

17

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

bashが対話型ログインシェルとして、または--loginオプションを使用した非対話型シェルとして起動されると、bashは最初にファイル/ 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番目のバージョンは問題なく動作します。


「sftp / scpツールが対話型の非ログインシェルを起動する」ということには同意しません。シェルと実際に対話できないからです。しかし、私はなぜ.bashrcscpまたはのソースになるのか理解できませんssh host command
pynexj

2
「インタラクティブ」という用語は主観的なものではありません。これは、bashがその起動モードの1つを記述するために使用する用語です。sftp / scpが「対話型の非ログインシェル」を開始するのは事実です。この場合、.bashrcの調達が適切かどうかについて、開発者と自由に議論してください。私はそれが何をするかをあなたに伝えているだけです。
Insyte

2
Bashによって呼び出されるscpssh host command、実際に非対話的です。私はちょうどbashマニュアルでこれを見つけました:~/.bashrc bash 、リモートシェルデーモン(通常はrshdまたはセキュアシェルデーモンsshd)によって実行されるときのように、ネットワーク接続に接続された標準入力で実行されているかどうかを判断しようとします。この方法で実行されており、そのファイルが存在し、読み取り可能な場合、コマンドを読み取り、実行します 。」ここに興味深い歴史があります。
pynexj

1
また、セクションを参照リモート非ログイン非対話型シェルをしてこのwikiページ
pynexj

3

cshを使用している場合:

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

そして、bashの場合:

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

または、bash正規表現を使用します。

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

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


こんにちは、コードを説明してください。私はそのことを知っていますか?前のコマンドの戻りレベルです。しかし、$?promptと$-を理解できません。または、csh固有ですか?
ジョエルGマシュー

1
@Droidzone:$?varin は、定義されているcsh場合varは1 を返し、定義されていない場合は0 を返します。なり持っているシェルが対話であれば、その値のcharを。$-bashi
pynexj

$-はシェルオプションの特別な変数であると説明するために回答を更新する必要があります。stackoverflow.com/questions/5163144/を

1

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

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

私は皆の利益のために共有すると思いました。


0

ここで言及した他のソリューションのいくつかはより良いものですが、誰かが有用な情報を見つけた場合に備えて、スタートアップスクリプトのエコーコマンドによる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"

少し強引ですが、機能します。


上記の["$ SSH_TTY"]コードを使用してみたところ、パテのような単純なクライアントプログラムでのみ機能することがわかりました。NoMachineを使用すると、何も出力されません。そのため、上記のコードに「xterm-256color」を含める必要がありました。
ボブヌーナン

興味深いことに、「if($?SSH_TTY)then」を使用してもcsh VMで機能しませんでした。チェックしましたが、SSH_TTY環境変数は定義されていません。したがって、上記の私のコードは、同様の状況にある他の人に役立つかもしれません。
ボブヌーナン

0

ここに私の(デフォルト).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モードの混乱を回避できます。

これがないと、あなたのファイルの場合は.bashrc用途echoや標準出力にいくつかの他のものの印刷には、エラーのこの種を取得することがあります。

  • SFTP: Received message too long 168435779
  • SCP: protocol error: unexpected <newline>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.