যুক্তিগুলির মাঝে কেন একটি ইওএফ আছে?


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 */])

( থ্রিজের উত্তর দেখুন )

$@একটি একক স্ট্রিং হিসাবে বিস্তৃত করতে ( বোঝার সাথে সাথে $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>

এটি স্পষ্ট যে "ফ্রম সিস" একটি যুক্তি হিসাবে পাইথনকে পাঠানো হচ্ছে।
পাইথন এটিই পায় এবং পাইথন "সিস থেকে" কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.