शेल स्क्रिप्ट में हाइब्रिड कोड। चर साझा करना


10

यह उत्तर एक टर्मिनल में कमांड लाइन से मल्टी-लाइन पायथन स्निपेट चलाने के तरीके पर चर्चा करता है। मैंने देखा कि उत्तर नेस्टेड इंडेंटेशन के साथ, शेल स्क्रिप्ट के भीतर भी महान काम करता है, जो बहुत अच्छा है, जैसे

#!/bin/bash
some_text="Hello world"
echo $some_text

cat <<EOF | python -
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF

प्रिंट:

0 
hello
hello
1
hello
hello
2
hello
hello

हालाँकि, मुझे शेल स्क्रिप्ट और पायथन स्निपेट के बीच चर साझा करने में मुश्किल समय आ रहा है।

  1. मैं बैश स्क्रिप्ट में पायथन सबस्क्रिप्ट के आउटपुट को कैसे एकत्र कर सकता हूं? (जैसे एक चर में जैसे $output)।

  2. मैं $some_textपायथन लिपि में एक बैश चर (जैसे ) कैसे पारित कर सकता हूं ?


1
आप python - <<EOFइसके बजाय कर सकते हैं ।

jftr imo यह खराब शैली है और आपको इससे बचने की कोशिश करनी चाहिए
उलरिच डेंगल

1
/ Zsh टैग क्यों?
स्टीफन चेजेलस

जवाबों:


12

अजगर के लिए एक चर हो रही है

चूँकि (जब EOFमार्कर को उद्धृत नहीं किया जाता है) चर प्रतिस्थापन तब होता है जब पाठ को हेरेडोक के pythonमानक इनपुट से पास किया जाता है, तो आप चर को स्क्रिप्ट में सही फेंक सकते हैं।

python - <<EOF
some_text = "$some_text"
EOF

तो some_textथा test, अजगर देखना होगा some_text = "test"। ध्यान दें कि यह एक कोड इंजेक्शन भेद्यता के रूप में देखा जा सकता है। तो some_textथा "; import os; os.system("evil-command"); x = ", उदाहरण के लिए, अजगर देखना होगा:

some_text = ""; import os; os.system("evil-command"); x = ""

और उस दुष्ट आज्ञा को चलाओ।

यदि आप बिना किसी संशोधन के अपने पायथन कोड को स्क्रिप्ट में सही तरीके से खींचना चाहते हैं, तो आप अपने चर का निर्यात कर सकते हैं।

export some_text

और os.environइसे पुनः प्राप्त करने के लिए उपयोग करें।

some_text = os.environ['some_text']

यह एक बहुत ही पवित्र / सुरक्षित दृष्टिकोण है।


पायथन से उत्पादन प्राप्त करना

स्क्रिप्ट के आउटपुट को इकट्ठा करने के लिए आप कमांड प्रतिस्थापन का उपयोग कर सकते हैं।

output=$(
python - <<EOF
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF
)

(ध्यान दें कि सभी अनुगामी न्यूलाइन वर्ण हटा दिए गए हैं)


यह बहुत अच्छा लग रहा है। जब आपने कहा "You could also pass the variable to the script as an argument", तो आप यह कैसे करेंगे कि यह विचार करते हुए कि पायथन लिपि शेल स्क्रिप्ट के भीतर सन्निहित है?
एमिलियो वाज़केज़-रीना

क्षमा करें, मैं एक सेकंड के लिए इसके बारे में भूल गया। मैंने उस समाधान को निकाल दिया है और बेहतर समाधान जोड़ा है।

सावधान रहें कि आप हेरेडोक मार्कर का नाम कैसे देते हैं। जब यह आपके उदाहरण के रूप में निर्विवाद है, शेल विस्तार हेरेडॉक स्ट्रिंग के भीतर होगा। उदाहरण के लिए, यदि आपके अजगर कोड में बस शामिल है print '$SHELL', तो आउटपुट होगा /bin/bashया आपका शेल जो भी होगा। यदि आप पहली पंक्ति को बदलते हैं python - <<'END', तो आउटपुट होगा $SHELL। यदि आप किसी कोड को bash स्क्रिप्ट में एम्बेड करने के लिए मौजूदा कोड को कॉपी और पेस्ट कर रहे हैं, तो आप लगभग निश्चित रूप से शेल प्रतिस्थापन नहीं चाहते हैं - आप चाहते हैं कि कोड उसी तरह से चले, जब वह किसी bash स्क्रिप्ट में एम्बेड नहीं होता है, ठीक है?
क्रिस जॉनसन

8

आपके दृष्टिकोण के साथ समस्या यह है कि एम्बेडेड पाइथन लिपि की अब मूल स्टडिन तक पहुँच नहीं है (क्योंकि इसकी स्टडिन ... ही है)।

यदि वह समस्या है तो आप लिख सकते हैं:

python -c '
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
'

या अगर अजगर स्क्रिप्ट में एकल उद्धरण हो सकते हैं:

python -c "$(cat << 'EOF'
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF
)"

या:

python <(cat << 'EOF'
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF
)

6

फ़ाइल नाम के रूप में डैश का उपयोग करें:

ruby - a b <<'END'
puts ARGV.join(",")
END

python - a b <<'END'
import sys
print ",".join(sys.argv[1:])
END

मुझे नहीं पता कि sys.argv[1:]पायथन में ऐसा करने का सही तरीका है या नहीं। -E / -c के साथ आप तर्क का अंत निर्दिष्ट कर सकते हैं -

set -- -a -b -c
ruby -e 'puts ARGV.join(",")' -- "$@"
python -c 'import sys; print ",".join(sys.argv[2:])' -- "$@"

आउटपुट कैप्चर करना और STDERR को पुनर्निर्देशित करना:

x=$(ruby <<'END' 2> /dev/null
puts "a"
abort "b"
END
)

2

1) आप अजगर में एक फ़ाइल के लिए चर असाइनमेंट लिख सकते हैं, और फिर अपनी बैश स्क्रिप्ट में स्रोत।

2) चूँकि आपका शब्द (EOF) उद्धृत नहीं किया गया है, यहाँ दस्तावेज़ की सभी पंक्तियों को पैरामीटर विस्तार के अधीन किया गया है। आप इसका उपयोग अजगर लिपि में सामान पास करने के लिए कर सकते हैं।

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