एक ssh शेल में वेरिएबल को एक्सपोर्ट करने वाले वेरिएबल की लिस्ट को क्यों प्रिंट करता है?


17

इस पर विचार करो:

$ ssh localhost bash -c 'export foo=bar'
terdon@localhost's password: 
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x HOME="/home/terdon"
declare -x LOGNAME="terdon"
declare -x MAIL="/var/spool/mail/terdon"
declare -x OLDPWD
declare -x PATH="/usr/bin:/bin:/usr/sbin:/sbin"
declare -x PWD="/home/terdon"
declare -x SHELL="/bin/bash"
declare -x SHLVL="2"
declare -x SSH_CLIENT="::1 55858 22"
declare -x SSH_CONNECTION="::1 55858 ::1 22"
declare -x USER="terdon"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SESSION_ID="c5"
declare -x _="/usr/bin/bash"

कमांड bash -cकी उस सूची में ssh परिणाम के माध्यम से चलने वाले सत्र के भीतर एक चर का निर्यात क्यों करता है declare -x(वर्तमान में निर्यात की गई चर की सूची, जहां तक ​​मैं बता सकता हूं)?

के बिना एक ही बात चल रहा bash -cहै कि:

$ ssh localhost  'export foo=bar'
terdon@localhost's password: 
$

और न ही ऐसा होता है यदि हम नहीं करते हैं export:

$ ssh localhost bash -c 'foo=bar'
terdon@localhost's password: 
$ 

मैंने इसे एक उबंटू मशीन से दूसरे (दोनों बैश 4.3.11 रनिंग) पर और एक आर्क मशीन पर दिखाया, जैसा कि ऊपर दिखाया गया है (bash संस्करण 4.4.5)।

यहाँ क्या चल रहा है? bash -cकॉल के अंदर एक चर निर्यात करने से यह उत्पादन क्यों होता है?


यह प्रश्न का उत्तर नहीं देता है, लेकिन आउटपुट चलने का परिणाम है export। Zsh ही काम करता है।
स्टीफन किट

@StephenKitt हाँ, मुझे पता है, मैं यह exportसमझने की कोशिश कर रहा हूँ कि क्या हो रहा है। मैं यह स्पष्ट करने के लिए संपादन करूंगा कि यह केवल निर्यात करते समय होता है।
terdon

आह ठीक है, मैंने पढ़ा "वर्तमान में निर्यात किए गए चर की सूची, जहां तक ​​मैं बता सकता हूं" का अर्थ है कि आप नहीं जानते थे कि आउटपुट कहां से आ रहा था।
स्टीफन किट

@StephenKitt मेरा मतलब है कि मुझे यकीन नहीं है कि अगर यह हर निर्यात चर या एक विशिष्ट उपसमुच्चय या क्या है। ओह! तुम्हारा मतलब है कि यह exportअकेले चलाने का उत्पादन है ? यह मैं नहीं समझ पाया था।
terdon

ध्यान दें कि foo=barसूची में दिखाई नहीं देता है।
डेल्टैब

जवाबों:


31

जब आप sshइसके माध्यम से एक कमांड चलाते हैं , तो इसे ध्वज के $SHELLसाथ कॉल करके चलाया जाता है -c:

-c    If the -c option is present, then commands are read from 
      the first non-option argument command_string.  If there  are
      arguments  after the command_string, the first argument is 
      assigned to $0 and any remaining arguments are assigned to
      the positional parameters.  

तो, ssh remote_host "bash -c foo"वास्तव में चलेगा:

/bin/your_shell -c 'bash -c foo'

अब, क्योंकि आप जिस कमांड को चला रहे हैं ( export foo=bar) में रिक्त स्थान हैं और पूरी तरह से बनाने के लिए ठीक से उद्धृत नहीं किया गया है, को exportचलाने के लिए कमांड के रूप में लिया जाता है और बाकी को स्थितीय मापदंडों के सरणी में सहेजा जाता है। इसका मतलब है कि exportइसे चलाया जाता है और foo=barइसे इस रूप में पारित किया जाता है $0। अंतिम परिणाम रनिंग के समान है

/bin/your_shell -c 'bash -c export'

सही आदेश होगा:

ssh remote_host "bash -c 'export foo=bar'"

9

ssh रिक्त स्थान के साथ तर्कों को सुगम बनाता है और दूरस्थ उपयोगकर्ता के लॉगिन शेल की व्याख्या करता है, इसलिए:

ssh localhost bash -c 'export foo=bar'

ssh की व्याख्या करने के लिए दूरस्थ खोल पूछ रहा है

bash -c export foo=bar

आदेश (प्रभाव में, यदि दूरस्थ होस्ट है यूनिक्स की तरह है, यह के साथ दूरदराज के खोल चलेंगे the-shell, -cऔर bash -c export foo=barतर्क के रूप में)।

अधिकांश गोले चल के रूप में कमांड लाइन की व्याख्या करेगा bashसाथ आदेश bash, -c, exportऔर foo=barतर्कों के रूप (ताकि चलाने exportजबकि $0शामिल foo=bar) आप इसके साथ इसे चलाने के लिए चाहते हैं, जबकि bash, -cऔर export foo=barतर्क के रूप में।

उसके लिए, आपको कमांड लाइन का उपयोग करना होगा:

ssh localhost "bash -c 'export foo=bar'"

(या:

ssh localhost bash -c \'export foo=bar\'

उस मामले के लिए) तो:

bash -c 'export foo=bar'

कमांड लाइन को रिमोट शेल में पास किया जाना चाहिए। उस कमांड लाइन की व्याख्या अधिकांश शेल द्वारा bashकमांड चलाने के रूप में की जाएगी bash, -cऔर export foo=barतर्क के रूप में। ध्यान दें कि का उपयोग कर

ssh localhost 'bash -c "export foo=bar"'

यदि दूरस्थ उपयोगकर्ता का लॉगिन शेल rcया esउदाहरण के लिए, जहां "एक विशेष उद्धरण ऑपरेटर नहीं है, तो काम नहीं करेगा । सिंगल कोट्स सबसे पोर्टेबल कोटिंग ऑपरेटर होते हैं (हालांकि शेल के बीच उनकी व्याख्या कैसे की जाती है, इसके बारे में कुछ भिन्नता है, देखें कि दूरस्थ उपयोगकर्ता के लॉगिन शेल को जाने बिना ssh पर एक मनमाना सरल कमांड कैसे निष्पादित करें? उस पर और अधिक के लिए)।

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