Sftp'yi kırmadan .bashrc kullanın


20

Benim sorunum birkaç değişken ayarlamak ve ssh kabuğuna her giriş yaptığımda birkaç satır çıktı gerekir ve aynı zamanda Filezilla üzerinden dosyaları tarnsfer için sftp kullanabilmek zorunda olmasıdır.

Şimdi, http://www.openssh.org/faq.html adresindeki openssh SSS'ye göre, başlangıç ​​komut dosyalarınız her türlü çıktıyı yansıtıyorsa, sftp ile karışır. Bu nedenle süresiz olarak gecikir veya "Çıkış kodu 128 ile sunucu tarafından kapatılan bağlantı" hatası verir.

.Bashrc .bash_profile için taşıma veya .bashrc içinde aşağıdaki kodu kullanarak gibi çözümler denedim:

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

Ve:

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

Ancak, hiçbir şey işe yaramıyor. Kabuk terminalim bash ve sftp'ye filezilla ile bağlanıyorum.

Yanıtlar:


23

Bunun yerine yapmayı deneyin

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

17

Mike'ın cevabı muhtemelen işe yarayacak. Ancak, ayrıntılı şeyleri hangi başlangıç ​​dosyalarına koyacağınızı dikkatlice seçebileceğinizi belirtmek gerekir. Bash man sayfasından:

Bash etkileşimli bir giriş kabuğu olarak veya --login seçeneğiyle etkileşimli olmayan bir kabuk olarak çağrıldığında, dosya varsa / etc / profilinden komutları okur ve yürütür. Bu dosyayı okuduktan sonra bu sırayla ~ / .bash_profile, ~ / .bash_login ve ~ / .profile arar ve var olan ve okunabilir olan ilk komutları okur ve yürütür. --Noprofile seçeneği, kabuk bu davranışı engellemeye başladığında kullanılabilir.

Oturum açma kabuğu olmayan bir etkileşimli kabuk başlatıldığında, bash bu dosya varsa ~ / .bashrc'den komutları okur ve yürütür. Bu, --norc seçeneği kullanılarak engellenebilir. --Rcfile dosyası seçeneği bash komutunu ~ / .bashrc yerine dosyadan okumaya ve yürütmeye zorlar.

Sftp / scp araçları etkileşimli bir oturum açma kabuğu başlatır, bu nedenle .bashrc kaynaklanır. Birçok dağıtım .bashrc kaynağını .bash_profile kaynağından ya da tam tersini sağlar, böylece kafa karıştırıcı olabilir. Giriş ortamınızın temizliğini test etmek için iyi bir hile, scp / sftp connect ile aynı şekilde simüle edilen bir komutla ssh etmektir. Örneğin: ssh myhost /bin/truescp / sftp bağlandıklarında tam olarak ne gördüğünü gösterir.

Basit bir demo:

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$

İlk test scp / sftp / rsync vb .'nin bozulmasına neden olur. İkinci sürüm gayet iyi çalışacaktır.


Kabuk ile gerçekten etkileşime giremediğimiz için "sftp / scp araçları etkileşimli bir oturum açma kabuğu başlatır" fikrine katılmıyorum . Ama neden anlamıyorum için source'd olacağını ya . .bashrcscpssh host command
pynexj

2
"Etkileşimli" terimi öznel değildir. Bu, bash tarafından başlangıç ​​modlarından birini tanımlamak için kullanılan bir terimdir. Bu, sftp / scp'nin "etkileşimli bir oturum açma kabuğu" başlattığı bir gerçektir. .Bashrc'nin bu durumda uygun olup olmadığı konusunda geliştiricilerle tartışmaktan çekinmeyin; Sadece sana ne yaptığını söylüyorum.
Mart'ta Insyte

2
Bashçağrılan scpveya ssh host commandgerçekten etkileşimli olmayan . Bunu sadece bash el kitabında buldum: "Bash , uzak kabuk arka plan programı, genellikle rshd veya güvenli kabuk arka plan programı sshd tarafından yürütüldüğü gibi, bir ağ bağlantısına bağlı standart girişi ile ne zaman çalıştırılacağını belirlemeye çalışır. bu şekilde çalıştırılıyorsa, bu dosya varsa ve okunabilirse, komutlarını okur ve yürütür . " ~/.bashrcİşte ilginç tarih .
pynexj

1
Ayrıca , bu wiki sayfasındaki Uzaktan oturum açma özelliği olmayan etkileşimli kabuklar bölümüne bakın .
pynexj

3

Csh kullanıyorsanız:

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

Ve eğer bash ise:

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

veya alternatif olarak bash düzenli ifadeleri kullanarak:

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

Bu satırlar, bir şeyi geri çevirdiğiniz / yankıladığınız satırlardan önce gelmelidir.


Merhaba, lütfen kodu açıklayabilir misiniz? $ Biliyorum? önceki komutun dönüş düzeyidir. $? İstemi ve $ - anlamıyorum. Yoksa csh'a özgü mü?
Joel G Mathew

1
@Droidzone: $?variçinde cshgeri dönüş ise 1 varbaşka şekilde tarif edilmediği ve 0. $-içinde bashmisiniz sahiptir ideğeri konusu toprağa kabuk interaktif ise.
Ocak'ta pynexj

$ Açıklamak için cevap güncelleme gerekir - kabuk seçenekleri özel bir değişkendir. bkz. stackoverflow.com/questions/5163144/…
maninvan

1

Mike'ın çözümü de benim için çalıştı. Ancak varsayılan kabuğum TCSH olduğundan, düzeltmeyi aşağıdaki gibi hafifçe düzenlemek zorunda kaldım (içinde .tcshrc):

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

Sadece herkesin yararına paylaşacağımı düşündüm.


0

Burada bahsedilen diğer çözümlerden bazılarını daha çok seviyorum, ancak herhangi birinin bilgiyi yararlı bulması durumunda, başlangıç ​​komut dosyalarındaki yankı komutları nedeniyle SFTP bağlantılarının kesilmesini önlemek için şu anda bash ve csh VM'lerimde kullandığım çözümü attığımı düşündüm. .

BASH'de:

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 cinsinden:

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"

Biraz kaba kuvvet ama işe yarıyor.


Yukarıdaki ["$ SSH_TTY"] kodunu kullanmayı denedim ve sadece macun gibi basit istemci programları için çalıştığını gördüm. NoMachine kullandığımda herhangi bir çıktı sağlamaz. Bu yüzden yukarıdaki kodda "xterm-256color" eklemem gerekiyordu.
Bob Noonan

İlginç bir şekilde, "if ($? SSH_TTY) then" kullanarak csh VM için de işe yaramadı. Kontrol ettim ve SSH_TTY ortam değişkeni tanımlanmadı. Bu yüzden yukarıdaki kodum benzer bir duruma sahip başkalarına yardımcı olabilir.
Bob Noonan

0

İşte benim (varsayılan) .bashrcdosyamın ilk satırları :

# ~/.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

Etkileşimli oturum kontrolü SCP, SFTP veya ssh remote-host commandmod ile uğraşmayı önler .

Bu olmadan, dosyanız stdout'ta yazdırma veya başka bir şey .bashrckullanıyorsa echo, bu tür hatalar alabilirsiniz:

  • SFTP: Received message too long 168435779
  • SCP: protocol error: unexpected <newline>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.