&& এবং | এর মধ্যে পার্থক্য কী বাশ স্ক্রিপ্টে?


13

আসুন নীচে দুটি লাইন নিন যা আমাদের দুটি পৃথক ফলাফল দেয়।

p=$(cd ~ && pwd) ; echo $p
p=$(cd ~ |  pwd) ; echo $p

কীভাবে দু'জনের মধ্যে পার্থক্য রয়েছে?


ধন্যবাদ আপনি কি আমার ক্ষেত্রে পার্থক্য পেতে পারেন? ধন্যবাদ।
নাম জি ভিউ

1
ইঙ্গিত:| সাবশেলে রানের দুপাশে কমান্ডগুলি ।
হিমাইল

উত্তর:


21

ইন p=$(cd ~ && pwd):

  • কমান্ড সাবস্টিটিউশন, $()একটি সাব-শেইলে চলে

  • cd ~ডিরেক্টরিটি ~(আপনার বাড়ীতে) পরিবর্তিত করে , যদি cdসফল হয় ( &&) তবে pwdSTDOUT এ ডিরেক্টরিটির নাম মুদ্রণ করে, সুতরাং এতে সংরক্ষিত স্ট্রিংটি pআপনার হোম ডিরেক্টরি যেমন/home/foobar

ইন p=$(cd ~ | pwd):

  • আবার $()একটি সাবশেল তৈরি করে

  • উভয় পক্ষের কমান্ডগুলি |সংশ্লিষ্ট সাবশেলগুলিতে চালিত হয় (এবং উভয়ই একই সাথে শুরু হয়)

  • তাই cd ~একটি subshell মধ্যে সম্পন্ন করা হয়, এবং pwdএকটি পৃথক subshell

  • সুতরাং আপনি কেবল স্টাডিউট পাবেন, pwdযেখানে আপনি কমান্ডটি চালাবেন সেখান থেকে, এটি কোনও ডিরেক্টরি হতে পারে আপনি কল্পনা pকরেই দেখতে পারেন, সুতরাং আপনার ডিরেক্টরি ডিরেক্টরি নয়, যেখানে কমান্ডটি আহ্বান করা হয়েছে সেখান থেকে ডিরেক্টরিটির নাম থাকবে,


কমান্ডগুলির মধ্যে পাইপের উদ্দেশ্য কী? cd ~কোনও আউটপুট উত্পাদন করে না, এবং pwdকোনও ইনপুট পড়ে না।
বার্মার

দ্বিতীয় কমান্ড মূলত সমান (cd ~);p=$(pwd)নয় কি?
বার্মার

@ বারমার হ্যাঁ, এটি ওপি ব্যবহার করেছে, এবং আমি কেবল তার জন্য এটি ব্যাখ্যা করছি।
হিমাইল

7

কোর ইস্যু কিভাবে অপারেটার হয় &&এবং |দুই কমান্ড সংযোগ।

&&প্রস্থান কোড মাধ্যমে কমান্ড সংযোগ করে। |ফাইল বর্ণনাকারী (stdin, stdout- এ) মাধ্যমে দুই কমান্ড সংযোগ করে।

প্রথমে সরলীকরণ করা যাক। আমরা অ্যাসাইনমেন্টটি সরিয়ে লিখতে পারি:

echo $(cd ~ && pwd)
echo $(cd ~ | pwd)

এটি বিশ্লেষণ করতে আমরা কমান্ড এক্সিকিউশন সাব-শেলটিকেও সরাতে পারি:

$ cd ~ && pwd
$ cd ~ | pwd

&&

কমান্ডগুলি কার্যকর করা হয় সেই ডিরেক্টরিটি প্রদর্শন করার জন্য যদি আমরা প্রম্পটটি পরিবর্তন করি তবে এর মতো কিছু PS1='\w\$ ', আমরা এটি দেখতে পাব:

/tmp/user$ cd ~ && pwd
/home/user
~$ 
  • কমান্ডটি cd ~"উপস্থিত ডিরেক্টরি "টিকে প্রকৃত ব্যবহারকারীর বাড়িতে পরিবর্তন করেছে যা কমান্ড ( /home/user) ব্যবহার করে।
  • কমান্ডের ফলাফল সফল হওয়ার সাথে সাথে (প্রস্থান কোড 0), অ্যান্ড অ্যান্ড এক্সিকিউট হওয়ার পরে পরবর্তী কমান্ডটি কার্যকর হয়েছিল
  • এবং "উপস্থিত ওয়ার্কিং ডিরেক্টরি" মুদ্রিত হয়।
  • চলমান শেল তার পরিবর্তিত হয়েছে pwdথেকে ~হিসেবে প্রম্পট দ্বারা প্রদর্শিত হয় ~$

ডিরেক্টরি পরিবর্তন যদি কোনও কারণে ব্যর্থ হয় (প্রস্থান কোড 0 নয়) কোনও কারণে (ডিরেক্টরি উপস্থিত নেই, ডিরেক্টরিটি পড়ার অনুমতি অনুমোদন করে) পরবর্তী কমান্ডটি কার্যকর করা হবে না।

উদাহরণ:

/tmp/user$ false && pwd
/tmp/user$ _ 

1 এর প্রস্থান কোড falseপরবর্তী কমান্ডটি কার্যকর করতে বাধা দেয়।

সুতরাং, "কমান্ড 1" এর প্রস্থান কোডটি "কমান্ড 2" কে প্রভাবিত করে।

এখন, পুরো কমান্ডের প্রভাবগুলি:

/tmp/user$ echo $(cd ~ && pwd)
/home/user
/tmp/user$ _

ডিরেক্টরিটি পরিবর্তন করা হয়েছিল, তবে একটি সাব-শেলের অভ্যন্তরে $(…)পরিবর্তিত ডিরেক্টরিটি মুদ্রণ করা হয়েছে /home/user, তবে সাব-শেলটি বন্ধ হয়ে যাওয়ার সাথে সাথে তা বাতিল করা হবে। পিডব্লিউডি প্রাথমিক ডিরেক্টরিতে ফিরে আসে ( /tmp/user)।

|

এটিই ঘটে:

/tmp/user$ cd ~ | pwd
/tmp/user
/tmp/user$ _

মেটা-অক্ষর |(সত্য অপারেটর নয়) শেলকে একটি "পাইপ" বলা হয় তা তৈরি করতে সিগন্যাল দেয়, (ব্যাশে) পাইপের প্রতিটি পাশের প্রতিটি কমান্ড |প্রতিটি নিজস্ব উপ-শেলের ভিতরে স্থাপন করা হয়, প্রথমে ডান পাশের কমান্ড, তারপর, বাম এক। /dev/stdinডান কমান্ডের ইনপুট ফাইল বর্ণনাকারী ( ) আউটপুট বর্ণনাকারী ( /dev/stdout) এর সাথে সংযুক্ত থাকে এবং তারপরে উভয় কমান্ড শুরু হয় এবং ইন্টারঅ্যাক্ট করতে বাম হয়। বাম কমান্ডের ( cd -) এর কোনও আউটপুট নেই এবং ডান কমান্ড ( pwd) কোনও ইনপুট গ্রহণ করে না। সুতরাং, প্রত্যেকে নিজের উপ-শেলের অভ্যন্তরে স্বতন্ত্রভাবে চালায়।

  • cd ~এক শেলের PWD পরিবর্তন।
  • pwd(সম্পূর্ণরূপে স্বাধীন) অন্য উপ-শেলের PWD ছাপে।

পাইপ শেষ হয়ে গেলে প্রতিটি শেলের পরিবর্তনগুলি বাতিল করা হয়, বাহ্যিক সাব-শেল পিডাব্লুডিকে পরিবর্তন করেনি।

এজন্য দুটি কমান্ড কেবল "ফাইল বর্ণনাকারী" দ্বারা সংযুক্ত রয়েছে।
এই ক্ষেত্রে, পাঠানো কিছুই নেই, এবং কিছুই পড়েনি।

পুরো আদেশ:

$ echo "$(cd ~ | pwd)"

কমান্ডটি কার্যকর হয়েছিল সেই ডিরেক্টরিটি কেবল মুদ্রণ করবে।


5

আমি নিশ্চিত না যে আপনি '|' বলতে চাইছেন কিনা বা '||' আপনার দ্বিতীয় ক্ষেত্রে

'|' শেলের মধ্যে একটি কমান্ডের আউটপুট অন্যটির ইনপুটটিতে পাইপ দেয় - সাধারণ ব্যবহারের ক্ষেত্রে এমন কিছু হয়: curl http://abcd.com/efgh | grep ijkl যেমন একটি কমান্ড চালান, এবং কমান্ডের আউটপুট প্রক্রিয়া করতে অন্য কমান্ড ব্যবহার করুন।

আপনি যে উদাহরণটি দিয়েছেন তা মোটামুটি অ-সংবেদনশীল, কারণ 'সিডি' সাধারণত কোনও আউটপুট উত্পন্ন করে না, এবং 'পিডব্লিউডি' কোনও ইনপুট আশা করে না।

'&&' এবং '||' যদিও অংশীদার কমান্ড। এগুলি বেশিরভাগ ভাষায় যৌক্তিক "এবং" এবং "বা" অপারেটরগুলির মতো একইভাবে ব্যবহার করার জন্য ডিজাইন করা হয়েছে। তবে যে অপটিমাইজেশনগুলি সম্পাদন করা হয় সেগুলি তাদের একটি শৈল প্রোগ্রামিং দৃষ্টান্ত হিসাবে একটি নির্দিষ্ট আচরণ দেয়।

যৌক্তিক "এবং" অপারেশনের ফলাফল নির্ধারণের জন্য, প্রথম শর্তটি সফল হলে আপনার কেবল দ্বিতীয় শর্তটি মূল্যায়ন করতে হবে - যদি প্রথম শর্তটি ব্যর্থ হয় তবে সামগ্রিক ফলাফল সর্বদা মিথ্যা হবে।

যৌক্তিক "বা" অপারেশনের ফলাফল নির্ধারণের জন্য, প্রথম শর্তটি ব্যর্থ হলে আপনাকে কেবল দ্বিতীয় শর্তটি মূল্যায়ন করতে হবে - যদি প্রথম শর্তটি সফল হয়, সামগ্রিক ফলাফল সর্বদা সত্য হবে।

সুতরাং, শেলটিতে, যদি আপনার command1 && command2 command2কেবলমাত্র কার্যকর command1ফলাফল কোডটি সম্পন্ন করে এবং ফিরে আসার পরে কার্যকর করা হবে । যদি আপনার ব্যর্থতার কোডটি প্রদান করে তবে সম্পূর্ণ হলে command1 || command2 command2তা কার্যকর করা হবে ।command1command1

আরেকটি সাধারণ দৃষ্টান্তটি হ'ল command1একটি পরীক্ষা কমান্ড হওয়া - এটি যদি / তারপরে বিবৃতি দেয় তবে এটি একটি একক লাইন উত্পন্ন করে - উদাহরণস্বরূপ:

[ "$VAR" = "" ] && VAR="Value if empty"

কোনও ভেরিয়েবলের কাছে মূল্য নির্ধারণের একটি (দীর্ঘ বাতাসযুক্ত) উপায় যদি এটি বর্তমানে খালি থাকে।

স্ট্যাক এক্সচেঞ্জের অন্য কোথাও এই প্রক্রিয়াটির ব্যবহারের উদাহরণ রয়েছে

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