एक ssh रिमोट कमांड का $ PATH एक इंटरैक्टिव शेल से अलग क्यों है?


20

मेरे पास एक उपयोगकर्ता है जिसने किसी भी डॉट-फाइल में $ PATH में कोई संशोधन नहीं किया है: यह सिस्टम डिफ़ॉल्ट सेटिंग है। एक लॉगिन शेल से:

$ 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

बिल्कुल निर्दिष्ट के रूप में /etc/profile। यह मुझे नहीं बल्कि अप्रत्याशित लगता है:

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

जैसा मैंने कहा ~/.bashrc, न तो $ PATH का कोई संशोधन है , न ही अंदर /etc/bash.bashrc~/.ssh/environmentया तो नहीं । ssh(1)घोषणा करता है कि वातावरण चर PATHहै

Ssh को संकलित करते समय, निर्दिष्ट PATH पर सेट करें।

लेकिन StackOverflow के इस धागे और इस मेलिंग सूची लेख का सुझाव है कि मुझे किसी दिए गए कमांड के लिए $ PATH को प्रभावित करने में सक्षम होना चाहिए बस / संशोधित प्रोफाइल /, शेल स्टार्टअप फ़ाइलों में से एक, आदि।

यहाँ क्या चल रहा है?

जवाबों:


16

से ssh(1)मैन्युअल पृष्ठ: "कमांड निर्दिष्ट है, तो यह एक लॉगिन खोल के बजाय दूरस्थ होस्ट पर निष्पादित किया जाता है।"

तो संक्षेप में जब आप वास्तव में मशीन बैश में प्रवेश करते हैं तो एक लॉगिन शेल के रूप में शुरू किया जाता है और जब आप दूरस्थ रूप से कनेक्ट होते हैं और बैश के स्थान पर इसे चलाया जाता है तो एक कमांड जारी करते हैं, जिसका मतलब है कि ये फाइलें लोड नहीं होती हैं। आप su -l -cssh के कमांड भाग में इसका उपयोग करके या इसके समान काम कर सकते हैं ।

कुछ मामलों में मैंने -tssh काम (tty आवंटित) के लिए भी तर्क देखा है।

संपादित करें 1 :
मुझे लगता है कि आपके द्वारा पाई गई PATH जानकारी, कि डिफ़ॉल्ट पथ (जब तक कि हम इसे ओवरराइड नहीं करते हैं) sdd में संकलित एक है। मैंने यह सुनिश्चित किया कि मेरे / etc / प्रोफाइल, / etc / bash *, स्थानीय dotfiles, आदि को इसमें कोई PATH जानकारी नहीं थी, फिर मैंने लॉग ऑन किया और अभी भी एक PATH था। मैंने इसे sshd में खोजा और इसे वहां पाया। तो इसका मेन्यू कैसे कहता है:

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

फिर मैं रिमोट पर PATH=$PATH:/my/testअपनी .bashrcफ़ाइल के शीर्ष पर जोड़ता हूं , और इसे फिर से जांचता हूं :

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

इसलिए मैं इसे पूरी तरह से प्रभावित कर सकता हूं, और डिफ़ॉल्ट PATH को sshd में संकलित किया गया है। :)


हम्म, उस वाक्यांश "दूरस्थ मेजबान पर निष्पादित" का अर्थ है कि यह जितना कहता है, उससे कहीं अधिक है। अधिक दिलचस्प बिट, जो मैंने पहले याद किया था, उसी मैनपेज के 'एनवायरनमेंट' सेक्शन में आता है: "SAT को संकलित करते समय निर्दिष्ट पैथ पर डिफ़ॉल्ट पथ सेट करें।" सिवाय इस पता चलता है कि मैं चाहिए एक आदेश के पथ को प्रभावित करने में सक्षम हो।
Troutwine

खैर बात यह है कि इसका लॉगिन शेल नहीं है, इसलिए यह रन / सोर्स नहीं करता है / स्टार्टअप फ़ाइलों को लॉगिन शेल के समान ही शामिल करता है, इसलिए मेरा सुझाव है कि इसे आज़माएं। बातें .bashrcकरना भी काम कर सकता है, लेकिन कुल मिलाकर मैं इसके चारों ओर काम करूंगा अगर पथ महत्वपूर्ण है। या यदि आप ssh को चलाने के 'कमांड' तरीके की आवश्यकता रखते हैं, तो केवल पूर्ण पथ निर्दिष्ट क्यों नहीं करते? :)
मटियास अहेनबर्ग

मैंने अपनी पोस्ट को थोड़ा संपादित किया है। अब, एक लॉगिन शेल, एक गैर-लॉगिन शेल और इसके बीच में इंटरैक्टिव / गैर-इंटरैक्टिव संस्करण हैं। गैर-संवादात्मक गैर-लॉगिन फ़ॉर्म में उपयोगकर्ता के शेल में SSH कमांड का उपयोग किया जाता है। bash(1)मंगलाचरण पता चलता है कि कोई स्टार्टअप फ़ाइलों इस फैशन में पढ़ा जाता है, लेकिन मैं पर प्रलेखन नहीं मिल सकता है कैसे ssh खोल लागू कर रहा है। जब तक दूसरों के पास / etc / ssh / sshrc स्टार्टअप फाइल सोर्सिंग है, जो मेरे पास नहीं है, तब तक यह लिंक किए गए स्रोतों के लिए काउंटर लगता है। (वर्कअराउंड हैं, निश्चित रूप से, लेकिन बिंदु बिल्कुल समझ में आ रहा है कि कैसे
डिबियन एसएसएचडी

यदि मैं /etc/profileमेरे लिए अपने दूरस्थ बॉक्स पथ अद्यतनों पर PATH को संशोधित करता हूं, तो ssh user@remotebox 'env'मुझे अद्यतन पथ दिखाता है। एक ही बात करता है, तो मैं जोड़ने के लिए चला जाता है export PATH=$PATH:/my/testpath(लेकिन इंटरैक्टिव गोले के लिए चेक से पहले (फ़ाइल के शीर्ष में मेरे मामले में .bashrc के लिए -z "$PS1")।
मैटिस Ahnberg

मेरे परीक्षणों / निष्कर्षों के साथ अपडेट किया गया।
मटियास अहेनबर्ग

3

मैं दूरस्थ पथ का उपयोग करके कमांड चलाने के लिए ssh प्राप्त करने में सक्षम था:

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

यहाँ env को कभी भी आपके द्वारा पसंद की जाने वाली कमांड से बदला जा सकता है।

मेरे पास अधिकृत कुंजियाँ हैं, इसलिए कमांड या ssh चलाने के लिए पासवर्ड की आवश्यकता नहीं है।


3

मैं समस्या को ठीक करने के लिए एक अलग समाधान के साथ आया था। मेरी व्यक्तिगत प्राथमिकता मौजूदा लोगों को बदलने के बजाय नई कॉन्फ़िगरेशन फ़ाइलें बनाना है। इस तरह मैं डिफ़ॉल्ट कॉन्फ़िगरेशन से परिवर्तनों को आसानी से नष्ट कर सकता हूं।

यहाँ की सामग्री हैं /etc/profile.d/ssh_login.sh:

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

dropbearइसके स्थान पर उपयोग करना openssh-server(यह ओपनश के साथ भी काम करना चाहिए), जब मैं दूरस्थ रूप से लॉग इन करता हूं तो SSH_CONNECTION चर स्वचालित रूप से सेट हो जाता है। मैंने SSH लॉगिन का पता लगाने के लिए एक नया शेल प्रोफ़ाइल कॉन्फ़िगरेशन बनाया, स्क्रीन पर कुछ जानकारी प्रदर्शित करता है और सबसे महत्वपूर्ण बात यह है /etc/environmentकि संकलित-मानों को बदलने के लिए वैश्विक पर्यावरण सेटिंग्स को लोड करें । कृपया ध्यान दें कि यह केवल इंटरैक्टिव एसएसएच गोले को प्रभावित करता है, न कि रिमोट कमांड निष्पादन।

वैकल्पिक रूप से , यदि आप ओपनश का उपयोग करते हैं और हमेशा वैश्विक वातावरण को लोड करना चाहते हैं, भले ही यह एक इंटरेक्टिव शेल हो, तो आप ~/.ssh/इस तरह से सिमलिंक लगा सकते हैं :

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

फिर आपको PermitUserEnvironmentविकल्प को सक्षम करने की आवश्यकता है /etc/sshd/sshd_config। केवल विश्वसनीय उपयोगकर्ताओं के लिए ऐसा करें, क्योंकि यह उन्हें LD_PRELADAD जैसे तंत्रों का उपयोग करते हुए कुछ कॉन्फ़िगरेशन में पहुँच प्रतिबंधों को बायपास करने में सक्षम कर सकता है। कृपया man sshd_configअधिक जानकारी के लिए देखें, विशेष रूप Matchसे विशिष्ट उपयोगकर्ताओं / समूहों के लिए अवरोधों के विकल्पों का उपयोग कैसे करें।


0

यदि आप प्रोफ़ाइल पथ को लोड करना चाहते हैं, तो प्रयास करें:

#!/bin/bash -i

स्क्रिप्ट के शीर्ष पर। इस तरह से स्क्रिप्ट चलाने के दौरान शेल इंटरैक्टिव मोड में है।

जब बैश को एक इंटरेक्टिव लॉगिन शेल के रूप में या एक गैर-इंटरेक्टिव शेल के रूप में - एल्गिन विकल्प के रूप में लागू किया जाता है, तो यह पहले फ़ाइल / आदि / प्रोफाइल से कमांड को पढ़ता है और निष्पादित करता है, यदि वह फ़ाइल मौजूद है। उस फ़ाइल को पढ़ने के बाद, यह उस क्रम में ~ / .bash_profile, ~ / .bash_login और ~ / .profile की तलाश करता है, और पहले मौजूद से कमांड पढ़ता और निष्पादित करता है और पढ़ने योग्य होता है। जब इस व्यवहार को रोकने के लिए शेल शुरू किया जाता है - तो नोप्रोफाइल विकल्प का उपयोग किया जा सकता है।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.