কীভাবে একটি শেবাং (যেমন #!) এর সাথে একাধিক যুক্তি ব্যবহার করবেন?


118

আমি একটি শেবাং--re-interval ব্যবহার করে একটি গাওক স্ক্রিপ্ট কার্যকর করতে চাই । "নিষ্পাপ" পদ্ধতির

#!/usr/bin/gawk --re-interval -f
... awk script goes here

কাজ করে না, যেহেতু গাওককে প্রথম আর্গুমেন্ট "--re-interval -f"(হোয়াইটস্পেসের চারপাশে বিভক্ত করা হয় না) দিয়ে ডাকা হয় , যা এটি বুঝতে পারে না। এটির জন্য কি কোনও কার্যকারিতা রয়েছে?

অবশ্যই আপনি সরাসরি গাককে কল করতে পারবেন না তবে এটি প্রথমে যুক্তিটি বিভক্ত করে এমন শেল স্ক্রিপ্টে মুড়িয়ে ফেলতে পারেন, বা একটি শেল স্ক্রিপ্ট তৈরি করুন যা গাককে কল করে এবং স্ক্রিপ্টটিকে অন্য কোনও ফাইলে রাখবে, তবে আমি ভাবছিলাম যে এর কিছু উপায় আছে কিনা? এটি একটি ফাইলের মধ্যে।

শেবাং লাইনের আচরণ সিস্টেম থেকে সিস্টেমে আলাদা হয় - কমপক্ষে সাইগউইনে এটি আর্গুমেন্টগুলিকে সাদা স্থান দ্বারা বিভক্ত করে না। আমি কেবল এমন সিস্টেমে এটি কীভাবে করব সে সম্পর্কে যত্নশীল; স্ক্রিপ্টটি বহনযোগ্য নয়।


1
আমি কেবল একটি নিরীহ পরীক্ষা করেছিলাম একটি স্ক্রিপ্টটি শেবাং লাইনে অন্য স্ক্রিপ্ট ব্যবহার করে যা আর্গুমেন্টগুলি সঠিকভাবে বিভক্ত করে।
হাস্তুরকুন

@ হস্তুরকুন, এটি আরেকটি বিষয় উত্থাপন করে যে, শেবাং লাইনের আচরণও সিস্টেমের থেকে সিস্টেমের প্রতি আলাদা হয়ে যায় যদি অনুরোধ করা প্রোগ্রামটি নিজেই কোনও স্ক্রিপ্ট হতে পারে।
dubiousjim


গাওকের সাম্প্রতিক সংস্করণগুলির সাথে (> = 4.0) --re-intervalএখন আর দরকার নেই (দেখুন [ gnu.org/software/gawk/manual/… )।

উত্তর:


25

এটি (g) awk সহ আমার পক্ষে কাজ করে বলে মনে হচ্ছে।

#!/bin/sh
arbitrary_long_name==0 "exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@"


# The real awk program starts here
{ print $0 }

উল্লেখ্য #!রান /bin/sh, তাই এই স্ক্রিপ্ট প্রথম একটি শেল স্ক্রিপ্ট হিসেবে ব্যাখ্যা করা হয়।

প্রথমে, আমি সহজভাবে চেষ্টা করেছি "exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@", কিন্তু অ্যাডক এটি একটি কমান্ড হিসাবে বিবেচনা করেছে এবং ইনপুটটির প্রতিটি লাইন নিঃশর্তভাবে মুদ্রণ করেছে। এজন্য আমি arbitrary_long_name==0এইটি রেখেছি - এটি সর্বদা ব্যর্থ হওয়ার কথা। আপনি এটি কিছু জিব্রিশ স্ট্রিং দিয়ে প্রতিস্থাপন করতে পারেন। মূলত, আমি খসখসে একটি মিথ্যা শর্তের সন্ধান করছিলাম যা শেল স্ক্রিপ্টকে বিরূপ প্রভাবিত করবে না।

শেল স্ক্রিপ্টে, arbitrary_long_name==0নামক একটি ভেরিয়েবল সংজ্ঞায়িত করে arbitrary_long_nameএবং এটির সমান সেট করে =0


এটি আমার উত্তর, তবে আমি অবাক হই যে এটি যথেষ্ট পরিমাণে বহনযোগ্য এবং শক্তিশালী। এটি কি বিশেষভাবে নির্ভর করে bash, বা এটি কোনও পসিক্সের সাথে কাজ করবে sh? এবং আমি awkপ্রায়শই ব্যবহার করি না , তাই আমি নিশ্চিত নই যে আমার রেখাটি দ্বিতীয় লাইনে লাইনটি awkউপেক্ষা করার জন্য জোর করার একটি ভাল উপায় ।
অ্যারন ম্যাকডেইড

আমি কী ভাবছিলাম, +1, তবে সম্ভবত অনিবার্য (অতএব আপেক্ষিক ভোট)।
অ্যারন হল

@ অ্যারনহল, এর কী কী সমস্যা থাকতে পারে তা আপনি ব্যাখ্যা করতে পারেন? যতক্ষণ ভেরিয়েবল arbitrary_long_nameআসল অ্যাজক প্রোগ্রামে ব্যবহৃত ভেরিয়েবলের সাথে সংঘর্ষ না করে, ততক্ষণ আমি কোনও সমস্যা দেখতে পাচ্ছি না। আমি কি অনুপস্থিত কিছু আছে?
অ্যারন ম্যাকডেইড

স্ক্রিপ্টটিকে বিপজ্জনক উপায়ে খারাপ আচরণ থেকে রক্ষা করার #!/bin/sh -পরিবর্তে ব্যবহার করুন #!/bin/shযদি -প্রথম চরিত্র হিসাবে জেরোথ আর্গুমেন্টের সাথে অনুরোধ করা হয়। এটি সি এর মতো প্রোগ্রামিং ভাষায় দুর্ঘটনাক্রমে ঘটতে পারে, যেখানে যুক্তিযুক্ত বিন্যাসের execveঅনুরূপ অংশ এবং অনুরূপ ক্রিয়াকলাপের অংশ হিসাবে চালিত প্রোগ্রামের নামটি ভুলে গিয়ে দুর্ঘটনাক্রমে গণ্ডগোল করা সহজ হয় এবং যদি লোকেরা অভ্যাসগতভাবে এটির বিরুদ্ধে সুরক্ষা দিতে ভুলে যায় তবে তাও হতে পারে কোনও আক্রমণকারীকে ইন্টারেক্টিভ শেল পেতে দেয় এমন দূষিতভাবে ব্যবহারযোগ্য দুর্বলতার শেষ ধাপ হিসাবে শেষ করুন।
mtraceur

161

শেবাং লাইনটি পসিক্স, এসইউএস, এলএসবি বা অন্য কোনও স্পেসিফিকেশনের অংশ হিসাবে নির্দিষ্ট করা হয়নি। আফাইক, এটি এমনকি সঠিকভাবে নথিভুক্ত করা হয়নি।

এটি কী করে তা নিয়ে মোটামুটি sensকমত্য রয়েছে: সবকিছুকে !এবং এর মধ্যে \nনিয়ে যান exec। অনুমানটি হ'ল !এবং এর মধ্যে থাকা সমস্ত \nকিছুই দোভাষীর সম্পূর্ণ পরিপূর্ণ পথ। এটিতে সাদা জায়গা থাকলে কী হয় সে সম্পর্কে happensক্যমত্য নেই।

  1. কিছু অপারেটিং সিস্টেম কেবল পুরো জিনিসটিকে পথ হিসাবে বিবেচনা করে। সর্বোপরি, বেশিরভাগ অপারেটিং সিস্টেমে শ্বেতস্পেস বা ড্যাশগুলি কোনও পথে আইনী।
  2. কিছু অপারেটিং সিস্টেম হোয়াইটস্পেসে বিভক্ত হয় এবং প্রথম অংশটিকে দোভাষীর পথ হিসাবে এবং বাকী অংশটিকে পৃথক যুক্তি হিসাবে বিবেচনা করে।
  3. কিছু অপারেটিং সিস্টেম প্রথম শ্বেত স্পেসে বিভক্ত হয় এবং সামনের অংশটিকে ইন্টারপেটারের পাথ এবং বাকী অংশকে একক যুক্তি হিসাবে দেখায় (যা আপনি দেখছেন)।
  4. এমনকি কিছু কিছু কুঁড়েঘর লাইন সমর্থন করি না এ সব

কৃতজ্ঞ, 1. এবং 4 মারা গেছে বলে মনে হয়, তবে 3. বেশ বিস্তৃত, সুতরাং আপনি কেবল একাধিক যুক্তি পাস করতে সক্ষম হয়ে নির্ভর করতে পারবেন না।

যেহেতু কমান্ড অবস্থান এছাড়াও POSIX বা বুনো উল্লেখিত না হয়, আপনি সাধারণত আপ এক্সিকিউটেবল এর ক্ষণস্থায়ী দ্বারা একক যুক্তি ব্যবহার নাম থেকে env, যাতে এটা এক্সিকিউটেবল এর অবস্থান নির্ধারণ করতে পারেন; উদাহরণ:

#!/usr/bin/env gawk

[স্পষ্টতই, এটি এখনও জন্য একটি নির্দিষ্ট পথ ধরেছে envতবে খুব কম সিস্টেমই রয়েছে যেখানে এটি বাস করে /bin, তাই এটি সাধারণত নিরাপদ। অবস্থান envঅবস্থান তুলনায় অনেক বেশি মান নির্ধারিত হয়েছে gawkবা মত এমনকি খারাপ কিছু pythonবা rubyবা spidermonkey।]

যার মানে আপনি আসলে ব্যবহার করতে পারবেন না কোনো আর্গুমেন্ট সব সময়ে


1
ফ্রিবিএসডি'র এনভির একটি -Sসুইচ রয়েছে যা এখানে সহায়তা করে, তবে এটি আমার envলিনাক্সটিতে উপস্থিত নেই এবং আমার সন্দেহ হয় যে জাইগুইনেও উপলভ্য নয়। @hstoerr, বিভিন্ন পরিস্থিতিতে অন্যান্য ব্যবহারকারীরা আপনার প্রশ্নগুলি পরে পড়তে পারেন, তাই সাধারণ পোর্টেবল উত্তরগুলি পছন্দনীয়, এমনকি যদি আপনার এখন বহনযোগ্যতার প্রয়োজন হয় না।
dubiousjim

4
সুতরাং আমরা একটি শেবাং এ যুক্তিগুলি বহনযোগ্যভাবে ব্যবহার করতে পারি না। কিন্তু যদি আমাদের কোনও উপায়ে প্রয়োজনীয় যুক্তি প্রয়োজন? আমি অনুমান করছি যে সমাধান মোড়কের শেল স্ক্রিপ্ট ধারণকারী লিখতে হয় #!/bin/shএবং /usr/bin/env gawk --re-interval -f my-script.awk। এটা কি ঠিক?
ররি ও'কেনে

1
আমি একমত না. আপনি যথেষ্ট যুক্তিযুক্তভাবে একটি যুক্তি ব্যবহার করতে পারেন। এমন কোনও সিস্টেম যেখানে আপনি কোনও যুক্তি ব্যবহার করতে পারবেন না এই traditionalতিহ্যবাহী ইউনিক্সবাদ বাস্তবায়নে মারাত্মকভাবে ব্যর্থ হয়, যা হ্যাশ-ব্যাং। অ-বাস্তবায়ন যদি ন্যায্য খেলা হয় তবে আমরা নিরাপদে বলতে পারি যে #!নিজে পোর্টেবল নয়। উদাহরণস্বরূপ, উইন্ডোজ এই কনভেনশনটিকে "নেটিভালি" মোটেই স্বীকৃতি দেয় না। ইউনিক্সে hasতিহ্যগতভাবে করতে সক্ষম হওয়ার জন্য একটি-তর্ক-তদন্তের প্রয়োজন #!/usr/bin/awk -f
কাজ

7
@ কাজ: হ্যাঁ, তবে যেহেতু অনেক বাইনারিগুলির পথ প্রমিত নয়, তাই আপনি নিজের একটি যুক্তি #!/usr/bin/env rubyবা পছন্দগুলি ব্যবহার করেন।
জার্গ ডব্লু মিটাগ

3
@ পেসারিয়র: পসিক্সের স্পেসিফিকেশনটি পরিবর্তন করুন এবং সমস্ত সিস্টেমটি অনুমিত অনুসারে আপডেট হওয়ার আগে 20-30 বছর অপেক্ষা করুন।
জার্গ ডব্লু মিট্টাগ

18

যদিও ঠিক পোর্টেবল নয়, কোর্টিলগুলি 8.30 দিয়ে শুরু করে এবং এর ডকুমেন্টেশন অনুসারে আপনি ব্যবহার করতে সক্ষম হবেন:

#!/usr/bin/env -S command arg1 arg2 ...

সুতরাং দেওয়া:

$ cat test.sh
#!/usr/bin/env -S showargs here 'is another' long arg -e "this and that " too

তুমি পাবে:

% ./test.sh 
$0 is '/usr/local/bin/showargs'
$1 is 'here'
$2 is 'is another'
$3 is 'long'
$4 is 'arg'
$5 is '-e'
$6 is 'this and that '
$7 is 'too'
$8 is './test.sh'

এবং আপনি যদি কৌতূহলী হন showargsতা হ'ল:

#!/usr/bin/env sh
echo "\$0 is '$0'"

i=1
for arg in "$@"; do
    echo "\$$i is '$arg'"
    i=$((i+1))
done

মূল উত্তর এখানে


1
এফওয়াইআই, ফ্রিবিএসডি বছরের কয়েক বছর ধরে রয়েছে (S.০ থেকে)। এটি কোর্টিলগুলিতে একটি স্বাগত বহনযোগ্যতা ability
হুয়ান

12

শ্বেত স্পেসগুলি যেভাবে শেবাংয়ের সাথে মোকাবেলা করা হয় (কমপক্ষে লিনাক্সে) তার কোনও আপত্তিজনক সমাধান ছাড়াই আমি একই ইস্যুটি নিয়ে এসেছি।

যাইহোক, যদি আপনি একটি কুঁড়েঘর বিভিন্ন অপশন প্রেরণ করতে পারেন, যতদিন তারা সংক্ষিপ্ত অপশন এবং তারা যেতে পারে ঘনিভূত (গনুহ উপায়)।

উদাহরণস্বরূপ, আপনি না করতে পারেন

#!/usr/bin/foo -i -f

কিন্তু আপনি করতে পারেন

#!/usr/bin/foo -if

স্পষ্টতই, এটি তখনই কার্যকর হয় যখন বিকল্পগুলির সংক্ষিপ্ত সমতুল্য থাকে এবং কোনও যুক্তি না নেয়।


11

সিগউইন এবং লিনাক্সের অধীনে শেবাংয়ের পথের পরে সবকিছুই একটি যুক্তি হিসাবে প্রোগ্রামটিতে বিশ্লেষণ করে।

awkশেবাংয়ের ভিতরে অন্য স্ক্রিপ্ট ব্যবহার করে এটি প্রায় হ্যাক করা সম্ভব :

#!/usr/bin/gawk {system("/usr/bin/gawk --re-interval -f " FILENAME); exit}

এটি {system("/usr/bin/gawk --re-interval -f " FILENAME); exit}awk এ কার্যকর করা হবে ।
এবং এটি /usr/bin/gawk --re-interval -f path/to/your/script.awkআপনার সিস্টেমের শেলের মধ্যে কার্যকর হবে ।


2
আপনি যদি স্ক্রিপ্টে যুক্তিগুলি পাস করেন তবে এই কাজ করবে না
স্টিভেন পেনি

4
#!/bin/sh
''':'
exec YourProg -some_options "$0" "$@"
'''

উপরের শেল শেবাং ট্রিকটি বেশি পোর্টেবল /usr/bin/env


'' ':' হোল্ড-ওভার কারণ আমার আসল সমাধানটি পাইগন স্ক্রিপ্টের জন্য ছিল তাই '' ':' পাইথন ইন্টারপ্রেটারকে এক্সিকিউট অংশটিকে উপেক্ষা করতে বলে।
ব্যবহারকারী3123730

4
আমি মনে করি আপনি নিম্নচ্যুত হচ্ছেন কারণ আপনার সমাধানটি এর জন্য python, তবে এই প্রশ্নটি প্রায় awk
অ্যারন ম্যাকডেইড

1
অজগর জন্য দুর্দান্ত হ্যাক।
জার হাই

3

গাক ম্যানুয়ালটিতে (http://www.gnu.org/manual/gawk/gawk.html) বিভাগের 1.14 এর শেষে উল্লেখ করুন যে শেবাং লাইন থেকে গাওক চলাকালীন আপনার কেবলমাত্র একটি যুক্তি ব্যবহার করা উচিত। এটি বলেছে যে ওএস সবকিছুর জন্য গাকের পথে সমস্ত একক যুক্তি হিসাবে বিবেচনা করবে। --re-intervalঅপশনটি নির্দিষ্ট করার জন্য অন্য কোনও উপায় আছে ? সম্ভবত আপনার স্ক্রিপ্টটি শেবাং লাইনে আপনার শেলটি রেফারেন্স করতে পারে, gawkকমান্ড হিসাবে চালিত হতে পারে এবং আপনার স্ক্রিপ্টের পাঠ্যটিকে "এখানে নথি" হিসাবে অন্তর্ভুক্ত করতে পারে।


মনে হচ্ছে বিকল্পটি নির্দিষ্ট করার কোনও অন্য উপায় নেই। আপনি ঠিক বলেছেন: গাক-ফ - << ইওএফ, স্ক্রিপ্টগুলির কয়েকটি লাইন, ইওএফ কাজ করে, তবে এটি আমাকে গাওয়াকের সাথে স্ট্যান্ডার্ড ইনপুট পড়তে বাধা দেয়।
হ্যান্স-পিটার স্টার

এখানে দস্তাবেজটির জন্য স্ট্যান্ডার্ড ইনপুট স্ট্রিমটি খায় gawkতবে আপনি এখনও ওভার স্ট্ডারগুলিতে কিছু পাইপ করতে সক্ষম হতে পারেন (এটি, এই স্ক্রিপ্টে পাইপ দেওয়ার আগে স্ট্ডআউটকে স্টার্ডারে পুনঃনির্দেশিত)। আমি বাস্তবে কখনও চেষ্টা করে দেখিনি তবে যতক্ষণ না প্রথম প্রক্রিয়া স্ট্যাডারের উপর কোনও কিছু নির্গত না করে, এটি কার্যকর হতে পারে। আপনি যদি নিশ্চিত হন যে অন্য কিছু ব্যবহার করছে না তা নিশ্চিত করতে চাইলে আপনি একটি নামক পাইপ ( লিনাক্সজার্নাল / কনটেন্ট / ইউজিং-নামড- পাইপস-ফিফস- বাশ ) ও তৈরি করতে পারেন।
বিটিএ

3

অতীতে শেবাং এড়াতে, স্ক্রিপ্টটি পড়তে, এবং ফাইল হিসাবে এটি দ্বিতীয় বারের মতো দিয়ে দেওয়ার জন্য কেন bashএবং gawkনিজেই ব্যবহার করবেন না gawk [--with-whatever-number-of-params-you-need]?

#!/bin/bash
gawk --re-interval -f <(gawk 'NR>3' $0 )
exit
{
  print "Program body goes here"
  print $1
}

(- এটি প্রাকৃতিকভাবে উদাহরণস্বরূপও সম্পন্ন হতে পারে sedবা tail, তবে আমি মনে করি যে কেবল bashএবং কেবল gawkনিজের উপর নির্ভর করে এক ধরণের সৌন্দর্য আছে ;)


0

কেবল মজাদার জন্য: নীচের বেশ কিছু অদ্ভুত সমাধান রয়েছে যা স্ট্রিডিন এবং প্রোগ্রামটি ফাইল বর্ণনাকারী 3 এবং 4 এর মাধ্যমে পুনরায় প্রবর্তন করে আপনি স্ক্রিপ্টের জন্য একটি অস্থায়ী ফাইলও তৈরি করতে পারেন।

#!/bin/bash
exec 3>&0
exec <<-EOF 4>&0
BEGIN {print "HALLO"}
{print \$1}
EOF
gawk --re-interval -f <(cat 0>&4) 0>&3

এটির জন্য একটি জিনিস বিরক্তিকর: শেলটি স্ক্রিপ্টে পরিবর্তনশীল প্রসার ঘটায়, তাই আপনাকে প্রতি $ (স্ক্রিপ্টের দ্বিতীয় লাইনে সম্পন্ন) উদ্ধৃত করতে হবে এবং সম্ভবত এর চেয়েও বেশি কিছু।


-1

পোর্টেবল সমাধানের জন্য, আপনার শেবাংয়ের সাথে স্ট্যান্ডার্ড বোর্ন শেল ( ) awkপরিবর্তে ব্যবহার করুন gawkএবং স্ট্যান্ডিনের পরিবর্তে কমান্ড লাইনে প্রোগ্রামটি এখানে নথিরূপে পাস করে সরাসরি অনুরোধ করুন:/bin/shawk

#!/bin/sh
gawk --re-interval <<<EOF
PROGRAM HERE
EOF

দ্রষ্টব্য: কোন -fযুক্তি awk। যে পাতা থেকে ইনপুট পড়ার stdinজন্য উপলব্ধ awk। ধরে নিলাম যে আপনি gawkইনস্টল করেছেন এবং PATHএটিতে, এটি আপনার মূল উদাহরণটি দিয়ে যা করার চেষ্টা করেছিলাম বলে আমার মনে হয় তা সবই অর্জন করে (ধরে নিই যে আপনি ফাইলের সামগ্রীটি অর্জ স্ক্রিপ্ট হিসাবে চেয়েছিলেন এবং ইনপুট নয়, যা আমি মনে করি যে আপনার শেবাং পদ্ধতির সাথে এটি আচরণ করা হত) )।


3
এটি আমার পক্ষে কাজ করেনি। বাশ লোকটি <<< ব্লেবলা স্ট্যাডিনের উপরে ব্লেবলা রাখে। আপনার অর্থ কি << - ইওফ? যেভাবেই হোক, এটি প্রোগ্রামকে স্টিডিনে রাখে।
হ্যান্স-পিটার স্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.