तर्कों के बीच में ईओएफ क्यों है?


20

मैं थोड़ा बैश फ़ंक्शन लिखना चाहता था ताकि मैं बैश बता सकूं, import osया from sys import stdoutयह आयातित मॉड्यूल के साथ एक नया पायथन दुभाषिया पैदा करेगा।

बाद का fromकार्य इस तरह दिखता है:

from () {
    echo "from $@" | xxd
    python3 -i -c "from $@"
}

अगर मैं इसे कॉल करता हूं:

$ from sys import stdout
00000000: 6672 6f6d 2073 7973 2069 6d70 6f72 7420  from sys import 
00000010: 7374 646f 7574 0a                        stdout.
  File "<string>", line 1
    from sys
           ^
SyntaxError: invalid syntax
>>> 

बाइट्स में from sysहैं

66 72 6f 6d 20 73 79 73 20
f  r  o  m     s  y  s    

इसमें कोई ईओएफ नहीं है, फिर भी पायथन इंटरप्रिटर ऐसा व्यवहार कर रहा है मानो ईओएफ पढ़ा हो। धारा के अंत में एक नई रूपरेखा है, जिसकी उम्मीद की जानी है।

fromएक बहन, जो एक पूरे पायथन मॉड्यूल का आयात करती है, इस तरह दिखती है, और जो स्ट्रिंग को साफ करने और संसाधित करने और गैर-मौजूद मॉड्यूल पर विफल होने से समस्या को हल करती है।

import () {
  ARGS=$@
  ARGS=$(python3 -c "import re;print(', '.join(re.findall(r'([\w]+)[\s|,]*', '$ARGS')))")
  echo -ne '\0x04' | python3 -i
  python3 -c "import $ARGS" &> /dev/null
  if [ $? != 0 ]; then
    echo "sorry, junk module in list"
  else
    echo "imported $ARGS"
    python3 -i -c "import $ARGS"
  fi
}

यह धारा में एक अस्पष्टीकृत ईओएफ की समस्या को हल करता है, लेकिन मैं यह समझना चाहता हूं कि पायथन को क्यों लगता है कि ईओएफ है।

जवाबों:


42

इस स्टैक ओवरफ्लो उत्तर में तालिका (जो बैश हैकर्स विकी से मिली ) बताती है कि विभिन्न बैश चर का विस्तार कैसे किया जाता है:

आप कर रहे हैं python -i -c "from $@", जो में बदल जाता है python -i -c "from sys" "import" "stdout", और -cकेवल एक तर्क लेता है, इसलिए यह कमांड चला रहा है from sys। आप उपयोग करना चाहते हैं $*, जो कि विस्तार करेगा python -i -c "from sys import stdout"(यह मानकर कि $IFSयह परेशान है या किसी स्थान से शुरू होता है)।


2
इसे हटाने के लिए धन्यवाद, क्योंकि यह बहुमूल्य जानकारी है :)
बिल्ली

1
मुझे लगता है कि यह स्वीकृत उत्तर होना चाहिए क्योंकि यह वास्तव में समस्या को हल करता है, दूसरे ने समस्या को स्पष्ट किया, लेकिन यह समाधान या वैकल्पिक समाधान नहीं देता है
फेरीबग

अच्छा उत्तर। वह टेबल वास्तव में बैश हैकर्स विकी से आता है। क्या आप उचित एट्रिब्यूशन जोड़ सकते हैं और सत्यापित कर सकते हैं कि आपके पास वितरित करने का अधिकार है?
मोनिका

22

strace, हमेशा की तरह, दिखाएगा कि क्या चल रहा है:

bash-4.1$ echo $$
3458

और, कहीं और (या आप यह पता लगा सकते हैं strace bash ...कि फ़ंक्शन कॉल कैसे करें):

bash-4.1$ strace -ff -o blah -p 3458

और उस पहले शेल में वापस:

bash-4.1$ from sys import stdout
  File "<string>", line 1
    from sys
           ^
SyntaxError: invalid syntax
>>> 
bash-4.1$ 

और फिर वापस straceशेल में:

Process 3458 attached
Process 25224 attached
^CProcess 3458 detached
bash-4.1$ grep exec blah.*
blah.25224:execve("/usr/bin/python", ["python", "-i", "-c", "from sys", "import", "stdout"], [/* 54 vars */]) = 0

इस प्रकार, वास्तविक -cतर्क यह है -c "from sys"कि कैसे "$@"विस्तारित किया जाता है, या एक छोटा कमांड जो pythonबारफ्स पर है।


9

$@दोहरे उद्धरण चिह्नों में तत्वों की सूची "$1" "$2" "$3"आदि का विस्तार होता है ।

#!/bin/bash
expand () {
    for string in "from $@" ; do
        echo "$string"
    done
}

expand sys import stdout

अजगर को उम्मीद है कि कोड एक तर्क में होगा, न कि तर्कों की एक श्रृंखला में।


6

अजगर का आह्वान किया जा रहा है

execve("/usr/bin/python", ["python", "-i", "-c", "from sys", "import", "stdout"], [/* 54 vars */])

(देखें thrig का जवाब )।

$@एक स्ट्रिंग (एक समझदार $IFS) के रूप में विस्तारित होने के लिए , आप $*दोहरे उद्धरण चिह्नों का उपयोग कर सकते हैं :

python3 -i -c "from $*"

के साथ पुष्टि की strace -e execve:

execve("/usr/bin/python", ["python", "-i", "-c", "from sys import stdout"], [/* 54 vars */]) = 0

2

स्ट्रेस दिखाते हैं कि क्या तर्क दिए गए हैं। लेकिन यह देखने के लिए सबसे सरल तरीका है कि क्या संसाधित किया जा रहा है, printf '<%s> 'प्रत्येक प्रासंगिक लाइन से पहले जोड़ना है , और एक समापन echo(नई लाइन के रूप में उत्पन्न करने के लिए):

इसलिए, फ़ंक्शन को इसे बदला जा सकता है:

from () {
    printf '<%s> ' "from $@"; echo
    printf '<%s> ' python3 -i -c "from $@"; echo
}

और जब बुलाया:

$ from sys import stdout
<from sys> <import> <stdout> 
<python3> <-i> <-c> <from sys> <import> <stdout>

यह स्पष्ट है कि "सीज़ से" एक तर्क के रूप में अजगर को भेजा जा रहा है।
यही अजगर को प्राप्त होता है, और अजगर "सिस से" कार्य करता है।

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