SSH uzaktan kumanda komutu manuel olarak çalıştırıldığında neden daha az ortam değişkeni alıyor? [kapalı]


239

Bir makineye ssh ve çalıştırırsanız iyi çalışan bir komut var, ama gibi bir uzak ssh komutunu kullanarak çalıştırmayı denediğimde başarısız:

ssh user@IP <command>

Her iki yöntemi kullanarak "env" çıktısını karşılaştırmak farklı ortamlarda sonuçlanır. Makineye manuel olarak giriş yaptığımda ve env çalıştırdığımda, çalıştırdığımda çok daha fazla ortam değişkeni alıyorum:

ssh user@IP "env"

Neden olduğu hakkında bir fikrin var mı?


30
Bu soru neden tam olarak konu dışı olarak kapandı?
jottr

13
Muhtemelen programlama ile ilgili olmadığı için. Kapatılmak yerine Süper Kullanıcı'ya taşınmış olmalıdır.
Daniel H

8
bashkomut dosyası dili değil mi?
Dan Nissenbaum

Debian 8'de / etc / passwd içinde bir sebepten ötürü kabuğu değiştirmek zorunda kaldım. Hatta / bin / sh noktasının bash'a gelmesine izin vermek için tetiği yeniden yapılandırmak yardımcı olmadı.
user1050755

Yanıtlar:


173

Farklı mermi türleri vardır. SSH komut yürütme kabuğu etkileşimli olmayan bir kabuk iken, normal kabuğunuz bir giriş kabuğu veya etkileşimli kabuktur. Man bash'tan açıklama şöyle:

       Bir giriş kabuğu ilk argüman karakteri
       sıfır bir - veya bir --login seçeneğiyle başlar.

       Etkileşimli kabuk isteğe bağlı olmayan bir başlangıçtır
       bağımsız değişkenler ve standart girdisi olan -c seçeneği olmadan
       ve hatanın her ikisi de terminallere bağlıdır (belirlendiği gibi)
       isatty (3)) veya biri -i seçeneğiyle başlatılmıştır. PS1:
       set ve $ - bash etkileşimli ise i'yi içerir,
       kabuk betiği veya bu durumu test etmek için bir başlangıç ​​dosyası.

       Aşağıdaki paragraflarda bash'ın
       başlangıç ​​dosyaları. Dosyalardan herhangi biri mevcut ancak olamazsa
       okh bash bir hata bildirir. Tildes dosyada genişletildi
       Aşağıda Tilde Genişletme altında açıklanan adlar
       GENLEŞME bölümü.

       Bash etkileşimli bir giriş kabuğu olarak veya
       --login seçeneğiyle etkileşimli olmayan bir kabuk, önce
       / etc / profile dosyasından komutları okur ve yürütürse,
       bu dosya var. Bu dosyayı okuduktan sonra
       içinde ~ / .bash_profile, ~ / .bash_login ve ~ / .profile
       sıralayın ve ilk komutları okur ve yürütür
       mevcut ve okunabilir. --Noprofile seçeneği
       kabuk bu davranışı engellemeye başladığında kullanılmalıdır
       IOR.

       Bir giriş kabuğu çıktığında, bash komutları okur ve yürütür
       varsa, ~ / .bash_logout dosyasından.

       Giriş kabuğu olmayan etkileşimli bir kabuk olduğunda
       bash ~ / .bashrc komutlarını okur ve yürütür,
       bu dosya varsa. Bu,
       --norc seçeneği. --Rcfile dosyası seçeneği bash'ı zorlar
       komutları dosya yerine okumak ve yürütmek için
       ~ / .Bashrc.

       Bash etkileşimli olmayan bir şekilde başlatıldığında, bir kabuk çalıştırmak için
       örneğin, BASH_ENV değişkenini
       çevre, orada görünürse değerini artırır,
       ve genişletilmiş değeri okumak için bir dosyanın adı olarak kullanır
       ve çalıştırın. Bash aşağıdaki komut gibi davranır
       idam edildi:
              [-n "$ BASH_ENV"] ise; sonra . "$ BASH_ENV"; fi
       ancak PATH değişkeninin değeri arama yapmak için kullanılmaz
       dosya adı için.


7
Büyük cevap, bu tam olarak problemdi, gerekli ortam değişkenleri / etc / bashrc'de ikamet etti, bu da etkileşimli olmayan modda kaynaklanmadı. Onları / etc / profile taşımak sorunu çözdü. Çok teşekkür ederim!
Tom Feiner

1
Bu cevap sadece kısmi bir çözümde. Daha fazla bilgi: kaynak alınan çeşitli dosyalara farklı bir ortam değişkeni ekleyin (ör., SOURCED_SYSTEM_ETC_BASHRC'yi dışa aktarın): / etc / profile, etc / bashrc, ~ / .profile, ~ / .bash_profile, ~ / bashrc. Ardından Jenkins çıktısında bu benzersiz değişkeni arayın. Benim durumumda, / etc / bashrc dosyasını 'export SOURCED_SYSTEM_ETC_BASHRC = yes' içerecek şekilde güncelledim ve bu değişken düğüm için Jenkins günlüğünde ortaya çıktı. Benim durumumda, jenkins köleleri için ortam değişkenleri ayarlamak için / etc / bashrc'ye gitmeleri gerekiyor. Jenkins ssh giriş sadece kaynaklı / etc / bashrc.
Coder Roadie

Düzeltme: /etc/bash.bashrc, / etc / bashrc değil demek istedim.
Coder Roadie

37
Bu bir metin duvarı ssh user@host "bash --login -c 'command arg1 ...'", uzak kabuğun giriş ortamını ayarlayacağını vurgulamaya değer olacağını düşünüyorum . Alıntıladığınız bölümden bahsediyor, --loginancak bunu gözden kaçırmak kolay olurdu.
16:17

Bu yazı için teşekkür ederim ssh <ssh options> <IP> bash --login my_script.sh, uzak makinede bir komut dosyası çalıştırıyordum, bir tedavi JAVA_HOME
uyguluyorum ve

117

Komutu çalıştırmadan önce profili kaynaklamaya ne dersiniz?

ssh user@host "source /etc/profile; /path/script.sh"

Bunu değiştirmek için en iyi buluyorum olabilir ~/.bash_profile, ~/.bashrcya da her neyse.

(Burada olduğu gibi (linuxquestions.org) )


1
Bu sorun vardı, bu çözüm harika çalıştı.
Sam152

10
Her zaman sadece ortamı kaynaklamak için ekstra kod yazmak zorunda kalmanız çok saçma!
Michael

4
Biri nadiren bu tür şeyleri tekrar tekrar yazar, normalde bir senaryo içinde olur ve bu nedenle, çalıştığı sürece ne kadar "ekstra kod" olduğu önemli değildir: tm:
Ian Vaughan

1
Hem / etc / profile hem de ~ / .bash_profile kaynağına (kullanıcı yoluna eklemeler almak için) çalışırsam işe yarar ama çirkin. Komutu (benim durumumda xterm) "interaktif" giriş bilgisini kullanmasını ve uzak makinede kullanıcıya özel tam yolla sonlandırmanın daha kolay bir yolu olmalı mı?
Jess

ssh $ 1 "kaynak ~ / .bashrc; ~ / temp_unix.sh" Burada temp_unix.sh ihracat MANI_HOME = "mani deepak" var ama çalışmıyor.
mani deepak

90

Uzak ssh komutu çalıştırıldığında kabuk ortamı yüklenmiyor. Ssh ortam dosyasını düzenleyebilirsiniz:

vi ~/.ssh/environment

Biçimi:

VAR1=VALUE1
VAR2=VALUE2

Ayrıca, seçenek sshdiçin yapılandırmayı kontrol edin PermitUserEnvironment=yes.


1
mükemmellik! Yapabilirsem +100 :)
Dexter

VisualGDB "bash: gcc: komut bulunamadı" hatasıyla başarısız oldu ve bu çözüm bunu düzeltti.
KalenGi

fantastik. keşke bu yıllar önce bilmeseydim.
yerçekimi

Bu mükemmel bir cevap!
Jirapong

1
@ pg2455 Sunucunuzda sshd'yi her zaman yapılandıramazken (veya herkes için etkinleştirmek istemiyorsanız), yine de kullanıcı ortamınızı düzenleyebilirsiniz
dpedro

63

Benzer bir sorunum vardı, ama sonunda ~ / .bashrc tüm ihtiyacım olduğunu öğrendim.

Ancak, Ubuntu'da ~ / .bashrc işlemeyi durduran satıra yorum yapmak zorunda kaldım:

#If not running interactively, don't do anything
[ -z "$PS1" ] && return

8
Alternatif olarak, tüm "etkileşimli olmayan" kodunuzu bu satırın üzerine yerleştirebilirsiniz.
machineghost

güzel, çok zaman kazandım :) teşekkürler
Lance Pollard

Teşekkürler. Sadece return ifadesine sahip dosyanın adresinde bulunabileceğini ekleyerek /etc/bash.bashrc.
adarshr

Bu kodu değiştirmeden sunucuda atlamak için yine de var mı?
Yoni

Senaryomun neden çalışmadığını anlamak için çok zaman harcadım. Bu satırları .bashrc'ye koymanın iyi bir fikir olduğunu kim düşünmüştü ???
Sharcoux

4

Bu sorun için kolay bir çözüm buldum, hedef sistemde çalıştırmaya çalıştığım script.sh dosyasının üstüne kaynak / etc / profile eklemek oldu. Buradaki sistemlerde bu, script.sh tarafından ihtiyaç duyulan çevresel değişkenlerin bir oturum açma kabuğundan çalışıyormuş gibi yapılandırılmasına neden oldu.

Önceki yanıtlardan birinde ~ / .bashr_profile vs ... 'nin kullanılması önerildi. Ben bu konuda fazla zaman harcamak yoktu ama, sorun bu hedef sistemde farklı bir kullanıcı için ssh oturum açtığınız kaynak sistemindeki kabuk daha farklı bir kullanıcı için bu kaynak sistem kullanıcı neden olduğu ortaya çıktı ~ için kullanılacak ad.


Mükemmel! Soruna güzel bir satır çözüm.
corpico

3

~ / .Bashrc içinde etkileşimli olmayan bir kabuk olup olmadığını denetlemek istediğiniz ortam değişkenlerini dışa aktarmanız yeterlidir.

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.