Bir ssh uzak komutunun $ PATH değeri neden etkileşimli bir kabuktan farklı?


20

Herhangi bir nokta dosyalarında $ PATH hiçbir değişiklik yapmayan bir kullanıcı var: tam olarak sistem varsayılan ayardır. Bir giriş kabuğundan:

$ ssh example.com
user@example.com:~$ cat /tmp/hello.hs
#!/bin/bash

echo "$SHELL"
echo "$PATH"

user@example.com:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin

Tam olarak belirtildiği gibi /etc/profile. Bu oldukça beklenmedik buluyorum:

$ ssh example.com '/tmp/hello.sh'
/bin/bash       
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Dediğim gibi, $ PATH içinde ~/.bashrcveya içinde herhangi bir değişiklik yok /etc/bash.bashrc. Hayır ~/.ssh/environment. ssh(1)Ortam değişkeni olduğunu beyan PATHolduğunu

Ssh derlenirken belirtildiği gibi varsayılan PATH olarak ayarlayın.

ancak StackOverflow ve bu posta listesi makalesinden gelen bu iş parçacığı , / etc / profile, kabuk başlangıç ​​dosyalarından birini, vb. değiştirerek belirli bir komut için $ PATH'ı etkileyebilmem gerektiğini önerir .

Burada neler oluyor?

Yanıtlar:


16

Gönderen ssh(1)manuel sayfa: "komutu belirtilirse, bunun yerine bir giriş kabuğunun çalıştırmaktadır edilir."

Kısacası, aslında makineye giriş yaptığınızda, bash bir giriş kabuğu olarak başlatılır ve uygun dosyaları yükler, uzaktan bağlandığınızda ve bir komut verdiğinizde, bash yerine çalıştırılır, yani bu dosyalar yüklenmez. su -l -cSsh komut komutunu kullanarak veya benzerlerini kullanarak çalışabilirsiniz .

Bazı durumlarda ben de -tssh iş (tty tahsis) argüman gördüm .

Düzenleme 1 :
Ben bulduğunuz YOL bilgileri, varsayılan yol (biz geçersiz kılma sürece) sshd derlenmiş olduğunu düşünüyorum. Benim / etc / profile, / etc / bash *, yerel dotfiles, vb herhangi bir PATH bilgi yoktu emin yaptı, sonra oturum ve hala bir PATH vardı. Bunu sshd'de aradım ve orada buldum. Yani manpage şöyle diyor:

ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Sonra uzaktan kumandasımda PATH=$PATH:/my/testen üste ekliyorum .bashrcve tekrar kontrol ediyorum :

ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test

Bu yüzden onu kesinlikle etkileyebilirim ve varsayılan PATH, sshd'ye derlenmiş olanıdır. :)


Hmm, "uzak ana bilgisayarda yürütülen" ifadesi, sandığından çok daha fazla şey ifade ediyor. Daha önce kaçırdığım daha ilginç bit, aynı kılavuzun 'ÇEVRE' bölümünde geliyor: "PATH ssh derlenirken belirtildiği gibi varsayılan PATH olarak ayarlayın." Dışında bu ben düşündürmektedir gereken bir komuta PATH etkilemeye muktedir.
troutwine

Peki nokta onun bir giriş kabuğu değil bu yüzden / kaynak / başlangıç ​​dosyaları bir giriş kabuğu için aynı şekilde dahil değil, bu yüzden denemek için benim önerileri. Bir şeyleri koymak .bashrcda işe yarayabilir, ancak genel olarak PATH önemliyse etrafında çalışardım. Ya da ssh'yi çalıştırmak için 'command' yoluna ihtiyacınız varsa neden sadece tam yol adları belirtmeyesiniz? :)
Mattias Ahnberg

Yazımı biraz düzenledim. Şimdi, bir giriş kabuğu, giriş yapmayan bir kabuk ve etkileşimli / etkileşimli olmayan varyantları var. SSH komutları, kullanıcının kabuğunda etkileşimli olmayan oturum açma biçiminde çağrılır. bash(1)Çağırma hiçbir başlatma dosyası bu şekilde okunan olduğunu göstermektedir, ancak belgelerine bulamıyorum nasıl ssh kabuğunu başlatıyordur. Diğerlerinin sahip olmadığım / etc / ssh / sshrc başlangıç ​​dosyası kaynaklarına sahip olmadıkça, bu yukarıdaki bağlantılı kaynaklara karşı görünüyor. (Elbette geçici çözümler var, ancak mesele Debian
SSHD'nin

/etc/profileBenim için uzak kutu yolu güncellemelerimde PATH değerini değiştirirsem ssh user@remotebox 'env', güncellenmiş PATH'yi gösterir. Aynı şey, export PATH=$PATH:/my/testpath-z "$PS1"
.bashrc'ye eklersem

Testlerim / bulgularımla güncellendi.
Mattias Ahnberg

3

Uzak yolu kullanarak komutları çalıştırmak için ssh başardı:

ssh dist@d6 "bash --login -c 'env'"

Burada env istediğiniz komutla değiştirilebilir.

Yetkili anahtarlarım var, bu yüzden komutu veya ssh'yi çalıştırmak için bir parolaya gerek duymadım.


3

Sorunu çözmek için farklı bir çözüm buldum. Kişisel tercihim, mevcut olanları değiştirmek yerine yeni yapılandırma dosyaları oluşturmaktır. Bu şekilde değişiklikleri varsayılan yapılandırmadan daha kolay yok edebilirim.

İşte içeriği /etc/profile.d/ssh_login.sh:

#!/bin/sh
if [ "$SSH_CONNECTION" ]; then
    echo "User '$USER' logged in from '${SSH_CONNECTION%% *}'"
    . /etc/environment
fi

Kullanma dropbearyerine openssh-serverben uzaktan oturumu sırasında (bu da Openssh'ın ile çalışmalıdır), SSH_CONNECTION değişkeni otomatik olarak ayarlanır alır. SSH oturumlarını algılamak, ekranda bazı bilgileri görüntülemek ve en önemlisi /etc/environmentderlenmiş değerleri değiştirmek için genel ortam ayarlarını yüklemek için yeni bir kabuk profili yapılandırması oluşturdum . Lütfen bunun uzaktan komut yürütmeyi değil, yalnızca etkileşimli SSH mermilerini etkilediğini unutmayın.

Alternatif olarak , openssh kullanırsanız ve etkileşimli bir kabuk olup olmadığına bakılmaksızın her zaman genel ortamı yüklemek istiyorsanız, aşağıdaki ~/.ssh/gibi bir sembolik bağlantı yerleştirebilirsiniz :

ln -s /etc/environment ~/.ssh/environment

Sonra içindeki PermitUserEnvironmentseçeneği etkinleştirmeniz gerekir /etc/sshd/sshd_config. Bunu yalnızca güvenilir kullanıcılar için yapın, çünkü bu, LD_PRELOAD gibi mekanizmaları kullanarak bazı yapılandırmalardaki erişim kısıtlamalarını atlayabilmelerini sağlayabilir. Daha man sshd_configfazla bilgi için, özellikle Matchbelirli kullanıcılara / gruplara seçenekleri kısıtlamak için blokların nasıl kullanılacağını öğrenmek için lütfen daha fazla bilgi edinin .


0

Profil yolunun yüklenmesini istiyorsanız şunu deneyin:

#!/bin/bash -i

komut dosyasının üst kısmında. Bu şekilde, komut dosyasını çalıştırırken kabuk etkileşimli modda olur.

Bash etkileşimli bir giriş kabuğu 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.

http://linux.die.net/man/1/bash

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.