"পিএস কুড়াল" "#" ছাড়া চলমান বাশ স্ক্রিপ্টটি খুঁজে পাচ্ছে না কেন? হেডার?


13

আমি যখন এই স্ক্রিপ্টটি চালিত করি তখন নিহত না হওয়া পর্যন্ত চালানোর উদ্দেশ্যে ...

# foo.sh

while true; do sleep 1; done

... আমি এটি ব্যবহার করে এটি খুঁজে পাচ্ছি না ps ax:

>./foo.sh

// In a separate shell:
>ps ax | grep foo.sh
21110 pts/3    S+     0:00 grep --color=auto foo.sh

... তবে আমি যদি #!স্ক্রিপ্টে কেবল সাধারণ শিরোনাম যুক্ত করি ...

#! /usr/bin/bash
# foo.sh

while true; do sleep 1; done

... তারপর স্ক্রিপ্ট একই psকমান্ড দ্বারা সন্ধানযোগ্য ...

>./foo.sh

// In a separate shell:
>ps ax | grep foo.sh
21319 pts/43   S+     0:00 /usr/bin/bash ./foo.sh
21324 pts/3    S+     0:00 grep --color=auto foo.sh

কেন এমন হয়?
এটি একটি সম্পর্কিত প্রশ্ন হতে পারে: আমি ভেবেছিলাম " #" এটি একটি মন্তব্য উপসর্গ মাত্র এবং যদি তাই হয় তবে " #! /usr/bin/bash" এটি একটি মন্তব্য ছাড়া আর কিছুই নয়। তবে " #!" কি কেবলমাত্র মন্তব্যের চেয়ে কিছু বেশি তাত্পর্য রয়েছে?


আপনি কি ইউনিক্স ব্যবহার করছেন?
কুসালানন্দ

@Kusalananda - Linux এর linuxbox 3.11.10-301.fc20.x86_64 # 1 জন্য SMP বৃহঃ ডিসেম্বর 5 14:01:17 ইউটিসি 2013, x86_64, x86_64, x86_64 জিএনইউ / লিনাক্স
StoneThrow

উত্তর:


13

যখন বর্তমান ইন্টারেক্টিভ শেলটি হবে bash, এবং আপনি নো- #!লাইন সহ একটি স্ক্রিপ্ট চালান , তখন bashস্ক্রিপ্টটি চালানো হবে। প্রক্রিয়াটি ps axঠিক আউটপুটে প্রদর্শিত হবে bash

$ cat foo.sh
# foo.sh

echo "$BASHPID"
while true; do sleep 1; done

$ ./foo.sh
55411

অন্য টার্মিনালে:

$ ps -p 55411
  PID TT  STAT       TIME COMMAND
55411 p2  SN+     0:00.07 bash

সম্পর্কিত:


সম্পর্কিত বিভাগগুলি bashম্যানুয়ালটি গঠন করে :

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

প্রোগ্রামটি যদি কোনও ফাইল দিয়ে শুরু হয় #!তবে প্রথম লাইনের বাকী অংশটি প্রোগ্রামটির জন্য একজন দোভাষীকে নির্দিষ্ট করে। শেল অপারেটিং সিস্টেমগুলিতে নির্দিষ্ট দোভাষীকে সম্পাদন করে যা এই নির্বাহযোগ্য বিন্যাসটি নিজেরাই পরিচালনা করে না। [...]

এর অর্থ হ'ল ./foo.shকমান্ড লাইনে দৌড়ানো , যখন foo.shএকটি- #!লাইন থাকে না , সাবসেলের মধ্যে ফাইলের কমান্ডগুলি চালনার মতই হয়

$ ( echo "$BASHPID"; while true; do sleep 1; done )

সঙ্গে একটি সঠিক #!যেমন করতে লাইন ইশারা /bin/bash, এরকম হয়

$ /bin/bash foo.sh

আমি মনে করি আমি অনুসরণ করি, তবে আপনি যা বলেন তা দ্বিতীয় ক্ষেত্রেও সত্য: বাশ দ্বিতীয় ক্ষেত্রে স্ক্রিপ্টটিও চালায়, স্ক্রিপ্টটি ps" /usr/bin/bash ./foo.sh" হিসাবে চলমান দেখানোর সময় লক্ষ্য করা যায় । সুতরাং প্রথম ক্ষেত্রে, যেমন আপনি বলেছেন, বাশ স্ক্রিপ্টটি চালাবে, তবে সেই স্ক্রিপ্টটি কি দ্বিতীয় অবস্থার মতো কাঁটাযুক্ত বাশকে "কার্যকর" করার দরকার হবে না? (এবং যদি তা হয় তবে আমি কল্পনা করতে পারি যে এটি
গ্রেপ

@ স্টোনথ্রো আপডেট হওয়া উত্তর দেখুন।
কুসালানন্দ

"... আপনি একটি নতুন প্রক্রিয়া ব্যতীত" - ভাল, আপনি যে কোনও উপায়ে একটি নতুন প্রক্রিয়া পাবেন, $$সাবস্কেল ক্ষেত্রে ( echo $BASHPID/ bash -c 'echo $PPID') ক্ষেত্রে এখনও পুরানোটির দিকে ইঙ্গিত করা বাদে ।
মাইকেল হোমার

@ মিশেলহোমর আহ, এর জন্য ধন্যবাদ! আপডেট হবে।
কুসালানন্দ

12

যখন কোনও শেল স্ক্রিপ্ট শুরু হয় #!, তখন প্রথম পংক্তিতে শেল সম্পর্কিত যতটা মন্তব্য হয়। তবে প্রথম দুটি অক্ষর সিস্টেমের অন্য একটি অংশে অর্থপূর্ণ: কার্নেল। দুটি চরিত্রকে শেবাং#! বলা হয় । শেবাংয়ের ভূমিকা বুঝতে, আপনাকে বুঝতে হবে যে কোনও প্রোগ্রাম কীভাবে কার্যকর করা হয়।

একটি ফাইল থেকে একটি প্রোগ্রাম চালানোর জন্য কার্নেল থেকে কর্ম প্রয়োজন। এটি execveসিস্টেম কলের অংশ হিসাবে করা হয় । কার্নেলটির কাছে ফাইল অনুমতিগুলি যাচাই করা, কলিং প্রক্রিয়ায় বর্তমানে চলমান এক্সিকিউটেবল ফাইলের সাথে সম্পর্কিত সংস্থানসমূহ (মেমরি ইত্যাদি) মুক্ত করতে হবে, নতুন এক্সিকিউটেবল ফাইলের জন্য সংস্থানগুলি বরাদ্দ করতে হবে এবং নতুন প্রোগ্রামে নিয়ন্ত্রণ স্থানান্তর করতে হবে (এবং আরও বেশি কিছু যা আমি উল্লেখ করব না)। execveসিস্টেম কল বর্তমানে চলমান প্রক্রিয়ার কোড প্রতিস্থাপন; forkএকটি নতুন প্রক্রিয়া তৈরি করার জন্য একটি পৃথক সিস্টেম কল রয়েছে ।

এটি করার জন্য, কার্নেলকে এক্সিকিউটেবল ফাইলের ফর্ম্যাটটি সমর্থন করতে হবে। এই ফাইলটিতে মেশিন কোড থাকতে হবে, কার্নেল বুঝতে পারে এমনভাবে সংগঠিত। শেল স্ক্রিপ্টে মেশিন কোড থাকে না, সুতরাং এটি এভাবে চালানো যায় না।

শেবাং মেকানিজম কার্নেলটিকে অন্য প্রোগ্রামে কোডটি ব্যাখ্যা করার কাজটি পিছিয়ে দেওয়ার অনুমতি দেয়। যখন কার্নেল দেখেন যে এক্সিকিউটেবল ফাইলটি শুরু হয় #!, তখন এটি পরবর্তী কয়েকটি অক্ষর পড়ে এবং ফাইলের প্রথম লাইনটি (বিয়োগী নেতৃস্থানীয় #!এবং alচ্ছিক স্থান) অন্য ফাইলের পথ হিসাবে ব্যাখ্যা করে (যুক্তি যুক্তি, যা আমি এখানে আলোচনা করব না) )। যখন কার্নেলটিকে ফাইলটি নির্বাহ করতে বলা হয় /my/scriptএবং ফাইলটি লাইন দিয়ে শুরু হয় #!/some/interpreterতখন কার্নেলটি /some/interpreterযুক্তি দিয়ে সঞ্চালিত করে /my/script। এরপরে এটি /some/interpreterসিদ্ধান্ত নেওয়া /my/scriptউচিত যে এটি একটি স্ক্রিপ্ট ফাইল যা এটি কার্যকর করা উচিত।

কোনও ফাইলের মধ্যে কার্নেল বুঝতে পারে এমন কোনও ফর্ম্যাটে নেটিভ কোড না থাকলে এবং কোনও শেবাং দিয়ে শুরু না হলে কী হবে? ঠিক আছে, তাহলে ফাইলটি কার্যকরযোগ্য নয়, এবং execveত্রুটি কোড ENOEXEC(এক্সিকিউটেবল ফর্ম্যাট ত্রুটি) এর সাথে সিস্টেম কল ব্যর্থ হয় ।

এটি গল্পের শেষ হতে পারে তবে বেশিরভাগ শেলগুলি ফ্যালব্যাক বৈশিষ্ট্যটি প্রয়োগ করে। যদি কার্নেলটি ফিরে আসে ENOEXEC, শেলটি ফাইলের বিষয়বস্তুটি দেখে এবং এটি শেল স্ক্রিপ্টের মতো দেখায় কিনা তা পরীক্ষা করে। শেলটি যদি মনে করে যে ফাইলটি শেল স্ক্রিপ্টের মতো দেখাচ্ছে তবে এটি এটি নিজেই প্রয়োগ করে। এটি কীভাবে এটি করে তার বিশদটি শেলের উপর নির্ভর করে। আপনি ps $$আপনার স্ক্রিপ্টে যোগ করে কিছু ঘটছে তা দেখতে পারবেন এবং strace -p1234 -f -eprocess1234 শেলের পিআইডি যেখানে রয়েছে সেখানে প্রক্রিয়াটি দেখে আরও কিছু দেখতে পাবেন ।

ব্যাশে, এই ফলব্যাক প্রক্রিয়াটি কল করে প্রয়োগ করা হয় forkতবে তা নয় execve। চাইল্ড বাশ প্রক্রিয়াটি তার নিজের অভ্যন্তরীণ অবস্থাটি নিজেই পরিষ্কার করে এবং এটি চালানোর জন্য নতুন স্ক্রিপ্ট ফাইলটি খোলে। সুতরাং যে প্রক্রিয়াটি স্ক্রিপ্টটি চালায় সেগুলি এখনও মূল বাশ কোড চিত্র ব্যবহার করছে এবং আপনি যখন প্রাথমিকভাবে বাশকে ডাকলেন তখন মূল কমান্ড লাইন আর্গুমেন্টগুলি পাস হয়ে গেছে। এটিটি ksh একইভাবে আচরণ করে।

% bash --norc
bash-4.3$ ./foo.sh 
  PID TTY      STAT   TIME COMMAND
21913 pts/2    S+     0:00 bash --norc

বিপরীতে, ড্যাশ আর্গুমেন্ট হিসাবে পাস করা স্ক্রিপ্টের পথটি ENOEXECকল করে প্রতিক্রিয়া জানায় /bin/sh। অন্য কথায়, আপনি যখন ড্যাশ থেকে কোনও শেবাংলেস স্ক্রিপ্ট সম্পাদন করেন, তখন স্ক্রিপ্টটির সাথে শেবাং লাইন রয়েছে এমন আচরণ করে #!/bin/sh। Mksh এবং zsh একইভাবে আচরণ করে।

% dash
$ ./foo.sh
  PID TTY      STAT   TIME COMMAND
21427 pts/2    S+     0:00 /bin/sh ./foo.sh

দুর্দান্ত, উত্তর বোঝা। একটি প্রশ্ন আরই: ফ্যালব্যাক বাস্তবায়ন আপনি ব্যাখ্যা করেছেন: আমি মনে করি যেহেতু কোনও শিশু bashকাঁটাচামচ, তাই এটি argv[]তার পিতামাতার মতো একই অ্যারেতে অ্যাক্সেস পেয়েছে, এটি কীভাবে এটি জানে যে "আপনি যখন মূলত বাশকে আহ্বান করেছিলেন তখন মূল কমান্ড লাইন আর্গুমেন্টগুলি পাস হয়েছিল", এবং যদি সুতরাং, এ কারণেই বাচ্চাকে স্পষ্ট যুক্তি হিসাবে মূল লিপিটি পাস করা হয়নি (সুতরাং এটি গ্রেপ দ্বারা সন্ধানযোগ্য নয়) - এটি কি সঠিক?
স্টোনথ্রো

1
আপনি প্রকৃতপক্ষে কার্নেল শেবাং আচরণ বন্ধ করতে পারেন ( BINFMT_SCRIPTমডিউলটি এটি নিয়ন্ত্রণ করে এবং মুছে ফেলা যায় / প্রায়শই এটি সাধারণত কার্নেলের সাথে সংযুক্ত করা হয়) তবে এম্বেড থাকা সিস্টেম ব্যতীত আপনি কেন কখনও চাইবেন তা আমি দেখতে পাই না perhaps । এই সম্ভাবনার কার্যকর হিসাবে, ক্ষতিপূরণ দেওয়ার জন্য bashএকটি কনফিগারেশন পতাকা রয়েছে ( HAVE_HASH_BANG_EXEC)!
এরিকএফ

2
@ স্টোনথ্রো এটি এতটা নয় যে শিশু বাশ "মূল কমান্ড লাইন যুক্তিগুলি জানে", কারণ এটি তাদের পরিবর্তন করে না। একটি প্রোগ্রাম psকমান্ড লাইন আর্গুমেন্ট হিসাবে কি রিপোর্টগুলি পরিবর্তন করতে পারে তবে কেবলমাত্র একটি বিন্দু পর্যন্ত: এটি একটি বিদ্যমান মেমরি বাফারটি সংশোধন করতে হবে, এটি এই বাফারটিকে বড় করতে পারে না। সুতরাং যদি বাশ argvস্ক্রিপ্টটির নাম যুক্ত করার জন্য এটি সংশোধন করার চেষ্টা করে , এটি সর্বদা কার্যকর হয় না। সন্তানের " execveসিস্টেমের কল নেই" কারণ শিশুটি "একটি তর্ক বিতর্ক করা হয় না" । এটি কেবল একই বাশ প্রক্রিয়া চিত্র যা চলতে থাকে।
গিলস 'অশুভ হওয়া বন্ধ করুন'

-1

প্রথম ক্ষেত্রে, স্ক্রিপ্টটি আপনার বর্তমান শেল থেকে একটি কাঁটাচামচ করা শিশু দ্বারা চালিত হয়।

আপনার প্রথমে চালানো উচিত echo $$এবং তারপরে একটি শেলটি দেখুন যা আপনার শেলের প্রসেস আইডি হিসাবে প্যারেন্ট প্রসেস আইডি হিসাবে রয়েছে।

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