Bu, birkaç hafta önce buraya göndereceğim bir soru. Terdon gibi, a'nın.bashrc
yalnızca etkileşimli Bash mermileri için kaynaklandığını anladım, bu yüzden .bashrc
etkileşimli bir kabukta çalışıp çalışmadığını kontrol etmenin gereği yoktu . Kafa karıştırıcı bir şekilde, kullandığım tüm dağıtımların (Ubuntu, RHEL ve Cygwin) , mevcut kabuğun etkileşimli olmasını sağlamak için bir tür kontrol (test $-
veya $PS1
) yapıldı. Kargo kültü programlamasını sevmiyorum, bu yüzden bu kodun amacını anlamaya karar verdim .bashrc
.
Bash'in uzak mermiler için özel bir durumu var
Sorunu araştırdıktan sonra, uzak mermilere farklı şekilde davranıldığını keşfettim . Etkileşimli olmayan Bash kabukları normalde ~/.bashrc
başlangıçta komut çalıştırmazken , kabuk uzak kabuk arka plan programı tarafından çağrıldığında özel bir durum ortaya çıkar :
Bash, genellikle uzaktaki kabuk cini rshd
veya genellikle güvenli kabuk cini tarafından çalıştırıldığı gibi bir ağ bağlantısına bağlı standart girişi ile ne zaman çalıştırıldığını belirlemeye çalışır sshd
. Bash'in bu şekilde çalıştırıldığını belirlerse, bu dosya varsa ve okunabiliyorsa, ~ / .bashrc komutlarını okur ve yürütür. Olarak çağrıldığında bunu yapmaz sh
. --norc
Seçeneği bu davranışı engellemek için kullanılabilirler ve --rcfile
opsiyon okunacak başka bir dosya zorlamak için kullanılabilir, ancak hiçbiri rshd
ne de sshd
genel olarak kabuğu bu seçeneklerle çağırmaz veya belirtilen izin verir.
Örnek
Uzaktan kumandanın başına aşağıdakileri yerleştirin .bashrc
. (Eğer .bashrc
tarafından kaynaklanmışsa .profile
veya .bash_profile
test sırasında bunu geçici olarak devre dışı bırakın):
echo bashrc
fun()
{
echo functions work
}
Aşağıdaki komutları yerel olarak çalıştırın:
$ ssh remote_host 'echo $- $0'
bashrc
hBc bash
- Hiçbir
i
yer $-
kabuğu olduğunu gösterir etkileşimli olmayan .
- Lider yok
-
içinde $0
kabuk bir olmadığını gösterir giriş kabuğu .
Uzaktan kumandada tanımlanan Shell işlevleri .bashrc
de çalıştırılabilir:
$ ssh remote_host fun
bashrc
functions work
Ben fark ~/.bashrc
edilir sadece bir komut için argüman olarak belirtildiğinde kaynaklı ssh
. Bu mantıklı: ssh
normal bir giriş kabuğu başlatmak için kullanıldığında .profile
veya .bash_profile
çalıştırıldığında (ve .bashrc
yalnızca açıkça bu dosyalardan biri tarafından yapıldığında kaynaklanır).
.bashrc
(Etkileşimli olmayan) bir uzaktan kumanda komutunu çalıştırırken elde ettiğim en büyük yarar , kabuk işlevlerinin çalıştırılabilmesidir. Bununla birlikte, tipik bir komuttaki komutların .bashrc
çoğu yalnızca etkileşimli bir kabuk ile ilgilidir, örneğin kabuk etkileşimli olmadığı sürece diğer adlar genişletilmez.
Uzaktan dosya aktarımı başarısız olabilir
Bu genellikle etkileşimli bir oturum açma kabuğunu başlatmak için rsh
veya ssh
kullanıldığında veya etkileşimli olmayan kabukların komutları çalıştırmak için kullanıldığında bir sorun değildir . Ancak, bir sorun olabilir gibi programlar için rcp
, scp
ve sftp
kullanan uzaktan kabukları veri aktarımı için.
scp
Komut kullanılırken uzak kullanıcının varsayılan kabuğunun (Bash gibi) tam olarak başlatıldığı anlaşılıyor . Man sayfasında bu konuda bir şey yok - sadece veri aktarımı için scp
kullanılan bir söz ssh
. Bunun sonucu olarak, standart çıktıya basan herhangi bir komut varsa .bashrc
, dosya transferlerinin başarısız olacağı , örneğin
scp'nin hatasız olarak sonuçlanacağı sonucuna varılmıştır .
Ayrıca, 15 yıl öncesine ait bu Red Hat hata raporuna bakınız , / etc / bashrc'da (nihayetinde kapatılmış WONTFIX
) bir yankı komutu varken scp kesiliyor .
Neden scp
ve sftp
başarısız
SCP (Güvenli kopya) ve SFTP (Güvenli Dosya Aktarım Protokolü) , aktarılan dosyalar hakkında bilgi alışverişinde bulunmak için yerel ve uzak uçlar için kendi protokollerine sahiptir. Uzak uçtan beklenmeyen herhangi bir metin (yanlış) protokolün bir parçası olarak yorumlanır ve aktarım başarısız olur. Salyangoz Kitabından bir SSS'ye göre
Genellikle ne olur, olsa da, sunucudaki ya sistemdeki ifadeleri veya kullanıcı başına kabuğu başlatma dosyaları (vardır ki .bashrc
, .profile
,
/etc/csh.cshrc
, .login
amaçlanan giriş çıkış metin mesajları gibi (insanlar tarafından okunacak, vs.) fortune
, echo "Hi there!"
, vb.).
Bu tür bir kod yalnızca tty
standart girişe ekli olduğunda etkileşimli girişlerde çıktı üretmelidir
. Bu testi yapmazsa, bu metin mesajlarını ait olmadıkları yerlere ekler: bu durumda scp2
/ sftp
ve arasındaki protokol akışını kirletir sftp-server
.
Kabuk başlangıç dosyalarının tümüyle alakalı olmasının nedeni, sshd
kullanıcı adına herhangi bir programı başlatırken kullanıcının kabuğunu
kullanmasıdır (eg / bin / sh -c "command" kullanarak). Bu bir Unix geleneğidir ve avantajları vardır:
- Uzaktan komutlar çalıştırıldığında, kullanıcının olağan ayarları (komut takma adları, ortam değişkenleri, umask vb.) Etkindir.
- Bir hesabın kabuğunu devre dışı bırakmak için / bin / false olarak ayarlamanın genel uygulaması, sahibinin herhangi bir komutu çalıştırmasını engeller, kimlik doğrulaması yine de bir nedenden dolayı başarılı bir şekilde başarılı olmalıdır.
SCP protokolü ayrıntıları
SCP'nin nasıl çalıştığının ayrıntılarıyla ilgilenenler için, SCP protokolünün nasıl çalıştığını ayrıntılı olarak içeren ve SCP'nin uzaktaki konuşmacı kabuk profilleriyle çalıştırma hakkındaki ayrıntıları içeren ilginç bilgiler buldum. :
Örneğin, bunu uzak sistemdeki kabuk profilinize eklerseniz olabilir:
Eko ""
Neden sadece takılıyor? Yani nasıl bir şekilde geliyor scp
yılında kaynağında modu ilk protokol mesajın onay bekler. İkili değilse 0, bunun uzak bir sorun bildirimi olmasını bekler ve yeni satır gelene kadar daha fazla karakterin hata mesajı oluşturmasını bekler. İlk satırdan sonra başka bir yeni satır yazdırmadığınız için, scp
yereliniz bir döngüde kalır ve engellenir read(2)
. Bu scp
sırada , uzaktaki kabuk profili işlendikten sonra read(2)
, veri aktarımının başlangıcını gösteren ikili bir sıfır bekleyen aynı zamanda engelleme yapan lavabo modunda başlatıldı .
Sonuç / TLDR
Tipikteki ifadelerin .bashrc
çoğu sadece rsh
veya ile uzaktan komut çalıştırırken değil, etkileşimli bir kabuk için kullanışlıdır ssh
. Bu gibi durumlarda, kabuk değişkenleri, takma adlar ve işlevleri tanımlamak istenmez - veya gibi programları kullanarak dosyaları aktarırken herhangi bir metni standart çıktıya yazdırmak aktif olarak zararlıdır . Geçerli kabuğun etkileşimli olmadığını doğruladıktan sonra çıkma, en güvenli davranıştır .scp
sftp
.bashrc