"প্রতিধ্বনি $ (স্টাফ)" বা "প্রতিধ্বনি` স্টাফ "এর সাথে কী সমস্যা?


31

আমি নিম্নলিখিতগুলির মধ্যে একটি ব্যবহার করেছি

echo $(stuff)
echo `stuff`

(যেখানে stuffউদাহরণস্বরূপ pwdবা dateআরও জটিল কিছু)

তারপরে আমাকে বলা হয়েছিল যে এই বাক্য গঠনটি ভুল, একটি খারাপ অভ্যাস, অ-মার্জিত, অতিরিক্ত, রিডান্ট্যান্ট, অতিরিক্ত জটিল, একটি কার্গো কাল্ট প্রোগ্রামিং, নুবিশ, নিষ্পাপ ইত্যাদি is

কিন্তু কমান্ড আছে কাজ, তাই কি ঠিক কি ভুল আছে?


11
এটি অপ্রয়োজনীয় এবং তাই ব্যবহার করা উচিত নয়। বিড়ালের অনর্থক
dr01

7
echo $(echo $(echo $(echo$(echo $(stuff)))))এছাড়াও আছে অধিকার কাজ, এবং এখনও আপনি সম্ভবত এটি ব্যবহার করা হবে না? ;-)
পিটার - মনিকা

1
আপনি ঠিক সেই সম্প্রসারণটি দিয়ে কী করার চেষ্টা করছেন?
কৌতূহলী

@ কুরিয়াসগুয়ে আমি অন্য ব্যবহারকারীদের সাহায্য করার চেষ্টা করছি, তাই আমার উত্তর নীচে। সম্প্রতি, আমি কমপক্ষে তিনটি প্রশ্ন দেখেছি যা এই সিনট্যাক্সটি ব্যবহার করে। তাদের লেখকরা… বিভিন্ন চেষ্টা করার চেষ্টা করছিলেন stuff। : ডি
কামিল ম্যাকিয়েরোস্কি

2
এছাড়াও, আমরা সকলেই একমত হই না যে নিজেকে ইকো চেম্বারে আবদ্ধ রাখা বুদ্ধিমান ?? ;-)
পিটার - মনিকা

উত্তর:


63

TL; ড

একমাত্র আপনার stuffপক্ষে সম্ভবত কাজ করবে।



পুরো উত্তর

কি ঘটেছে

আপনি যখন দৌড়ান foo $(stuff), এটি ঘটে যা ঘটে:

  1. stuff রান;
  2. এর আউটপুট (stdout), মুদ্রণের পরিবর্তে, এর অনুরোধে প্রতিস্থাপন $(stuff)করে foo;
  3. তারপরে fooচলে, তার কমান্ড লাইনের যুক্তিগুলি স্পষ্টতই stuffফিরে আসে তার উপর নির্ভর করে ।

এই $(…)প্রক্রিয়াটিকে "কমান্ড সাবস্টিটিউশন" বলা হয়। আপনার ক্ষেত্রে প্রধান কমান্ড হ'ল echoমূলত স্ট্যান্ডআউটে তার কমান্ড লাইন আর্গুমেন্টগুলি মুদ্রণ করে। তাই যাই হোক না কেন stuffstdout- এ মুদ্রণ করার চেষ্টা করে বন্দী, এর পাস করা হয়েছে echoএবং stdout- এ মুদ্রিত echo

আপনি যদি আউটপুটটি stuffস্টডআউটে মুদ্রিত হতে চান তবে কেবল একক চালান stuff

`…`সিনট্যাক্স হিসাবে একই উদ্দেশ্য করে তোলে $(…)(একই নামের অধীনে: "কমান্ড প্রতিকল্পন"), তাই এগুলোকে অন্ধের মত না অদলবদল করতে পারেন, যদিও কয়েক পার্থক্য আছে। দেখুন এই FAQ এবং এই প্রশ্নের


আমি echo $(stuff)কি যাই হোক না কেন এড়ানো উচিত?

echo $(stuff)আপনি কী করছেন তা যদি জানেন তবে আপনি ব্যবহার করতে পারেন এমন একটি কারণ রয়েছে । echo $(stuff)আপনি কী করছেন তা যদি সত্যিই না জানেন তবে একই কারণে আপনার এড়ানো উচিত ।

বিষয়টি হ'ল stuffএবং echo $(stuff)সমতুল্য নয়। পরবর্তীটির অর্থ হ'ল stuffডিফল্ট মান সহ আউটপুটে স্প্লিট + গ্লোব অপারেটর কল করা $IFS। কমান্ড প্রতিস্থাপনের ডাবল উদ্ধৃতি এটি প্রতিরোধ করে। একক কমান্ড সাবস্টিটিউশন উদ্ধৃত করার ফলে এটি আর কমান্ডের বিকল্প হতে পারে না।

বিভাজন আসে যখন এই কমান্ডগুলি চালানোর জন্য এটি পর্যবেক্ষণ:

echo "a       b"
echo $(echo "a       b")
echo "$(echo "a       b")"  # the shell is smart enough to identify the inner and outer quotes
echo '$(echo "a       b")'

এবং গ্লোব্বিংয়ের জন্য:

echo "/*"
echo $(echo "/*")
echo "$(echo "/*")"  # the shell is smart enough to identify the inner and outer quotes
echo '$(echo "/*")'

যেমন আপনি দেখতে পাচ্ছেন echo "$(stuff)"এটি সমান (-শ *) stuff। আপনি এটি ব্যবহার করতে পারেন তবে জিনিসগুলিকে এভাবে জটিল করার উপায় কী?

অন্যদিকে যদি আপনি চান আউটপুট stuffবিভাজন + + globbing তারপর আপনি ভুগা পারে এটি echo $(stuff)দরকারী। যদিও এটি আপনার সচেতন সিদ্ধান্ত হতে হবে।

কমান্ডগুলি উত্পন্ন করার আউটপুট রয়েছে যা মূল্যায়ন করা উচিত (যার মধ্যে বিভাজন, গ্লোব্বিং এবং আরও অনেক কিছু রয়েছে) এবং শেল দ্বারা চালিত হয়, তাই eval "$(stuff)"সম্ভাবনা রয়েছে ( এই উত্তরটি দেখুন )। আমি কোনও কমান্ড কখনই দেখিনি যা মুদ্রণের আগে অতিরিক্ত বিভাজন + গ্লোব্বিংয়ের মধ্য দিয়ে আউটপুটটির প্রয়োজন হয় । ইচ্ছাকৃতভাবে ব্যবহার করা echo $(stuff)খুব অস্বাভাবিক মনে হচ্ছে।


কি হবে var=$(stuff); echo "$var"?

ভাল যুক্তি. এই স্নিপেট:

var=$(stuff)
echo "$var"

echo "$(stuff)"সমান (-শ *) এর সমতুল্য হওয়া উচিত stuff। এটি যদি পুরো কোড হয় তবে কেবল stuffতার পরিবর্তে চালান ।

তবে, যদি আপনাকে stuffএকাধিকবার আউটপুট ব্যবহার করতে হয় তবে এই পদ্ধতির

var=$(stuff)
foo "$var"
bar "$var"

সাধারণত তুলনায় ভাল

foo "$(stuff)"
bar "$(stuff)"

এমনকি যদি fooহয় echoএবং আপনি echo "$var"আপনার কোডটি পেয়ে থাকেন তবে এটিকে এভাবে রাখাই ভাল। বিবেচনা করার বিষয়গুলি:

  1. var=$(stuff) stuffএকবার রান দিয়ে ; কমান্ডটি দ্রুত হলেও, একই আউটপুট দু'বার গণনা করা এড়ানো সঠিক জিনিস। অথবা stuffস্টাডাউটে লেখার ব্যতীত অন্য কোনও প্রভাব থাকতে পারে (যেমন একটি অস্থায়ী ফাইল তৈরি করা, একটি পরিষেবা শুরু করা, ভার্চুয়াল মেশিন শুরু করা, রিমোট সার্ভারকে অবহিত করা), যাতে আপনি এটি একাধিকবার চালাতে চান না।
  2. যদি stuffসময় নির্ভর বা কিছুটা এলোমেলো আউটপুট উত্পন্ন করে তবে আপনি foo "$(stuff)"এবং থেকে বেমানান ফলাফল পেতে পারেন bar "$(stuff)"var=$(stuff)এর মান $varস্থির হওয়ার পরে এবং আপনি নিশ্চিত হতে পারেন foo "$var"এবং bar "$var"অভিন্ন কমান্ড লাইন যুক্তি পেতে পারেন ।

কিছু ক্ষেত্রে আপনার পরিবর্তে foo "$var"(প্রয়োজন) ব্যবহার করতে চান foo $var, বিশেষত যদি একাধিক যুক্তি stuffউত্পন্ন করেfoo (আপনার শেল সমর্থন করে তবে একটি অ্যারে ভেরিয়েবল আরও ভাল হতে পারে)। আবার, আপনি কি করছেন তা জানুন। এটা আসে যখন echoএর মধ্যে পার্থক্য echo $varএবং echo "$var"মধ্যবর্তী হিসাবে একই echo $(stuff)এবং echo "$(stuff)"


* সমান ( -শ )?

আমি বললাম echo "$(stuff)"সমতূল্য (পর) হল stuff। কমপক্ষে দুটি সমস্যা রয়েছে যা একে একে একে সমান নয়:

  1. $(stuff)stuffএকটি সাব-শেলের মধ্যে চলে , সুতরাং echo "$(stuff)"সমতুল্য (-শ) বললে ভাল (stuff)। কমান্ডগুলি যেগুলি চালিত শেলকে প্রভাবিত করে, যদি সাব-শেলতে থাকে তবে মূল শেলটিকে প্রভাবিত করবে না।

    এই উদাহরণে stuffহয় a=1; echo "$a":

    a=0
    echo "$(a=1; echo "$a")"      # echo "$(stuff)"
    echo "$a"
    

    এর সাথে তুলনা করুন

    a=0
    a=1; echo "$a"                # stuff
    echo "$a"
    

    এবং সাথে

    a=0
    (a=1; echo "$a")              # (stuff)
    echo "$a"
    

    আর একটি উদাহরণ, stuffসত্তা দিয়ে শুরু করুন cd /; pwd:

    cd /bin
    echo "$(cd /; pwd)"           # echo "$(stuff)"
    pwd
    

    এবং পরীক্ষা stuffএবং (stuff)সংস্করণ।

  2. echoঅনিয়ন্ত্রিত ডেটা প্রদর্শনের জন্য কোনও ভাল সরঞ্জাম নয় । এই echo "$var"আমরা কথা বলছিলাম উচিত ছিল printf '%s\n' "$var"। তবে যেহেতু প্রশ্নের উল্লেখ রয়েছে echoএবং যেহেতু সবচেয়ে সম্ভাব্য সমাধানটি echoপ্রথম স্থানে ব্যবহার না করা হয়েছে , তাই printfএখন অবধি পরিচয় না করানোর সিদ্ধান্ত নিয়েছি ।

  3. stuffঅথবা (stuff)স্টলআউট এবং স্টডার আউটপুট ইন্টারলিভ করবে, যখন echo $(stuff)সমস্ত স্টডার আউটপুট মুদ্রণ করবে stuff(যা প্রথমে চলে) এবং কেবল তখনই স্টাডআউট আউটপুট হজম করে echo(যা শেষ চলে)।

  4. $(…)যেকোন পেছনের নতুন লাইনটি স্ট্রিপ করে এবং তারপরে echoএটি আবার যুক্ত করে। সুতরাং echo "$(printf %s 'a')" | xxdবিভিন্ন আউটপুট দেয় printf %s 'a' | xxd

  5. কিছু কমান্ড ( lsউদাহরণস্বরূপ) স্ট্যান্ডার্ড আউটপুট কনসোল কিনা তা নির্ভর করে ভিন্নভাবে কাজ করে; সুতরাং ls | catএকই lsকরে না। একইভাবে echo $(ls)ভিন্ন চেয়ে কাজ করবে ls

    ফেলে lsএকটি সাধারণ ক্ষেত্রে সরাইয়া, যদি আপনি জোর করে অন্য আচরণ তারপর আছে stuff | catবেশী ভালো echo $(ls)বা echo "$(ls)"কারণ এটি আরম্ভ না সব অন্যান্য বিষয় এখানে উল্লেখ করেছে।

  6. সম্ভবত পৃথক প্রস্থান স্থিতি (এই উইকির উত্তরটির সম্পূর্ণতার জন্য উল্লেখ করা হয়েছে; বিশদগুলির জন্য আরও একটি উত্তর দেখুন যা creditণের দাবি রাখে)।


5
আরও একটি পার্থক্য: stuffউপায়টি আন্তঃলিভ stdoutএবং stderrআউটপুট দেবে, যখন echo `stuff` সমস্ত stderrআউটপুট প্রিন্ট করবে stuffএবং কেবল তখনই stdoutআউটপুট।
Ruslan

3
এবং এটির জন্য এটির আরও একটি উদাহরণ: ব্যাশ স্ক্রিপ্টগুলিতে খুব বেশি সংখ্যক উদ্ধৃতি থাকতে পারে। echo $(stuff)আপনাকে আরও বেশি সমস্যার মধ্যে ফেলে দিতে পারে echo "$(stuff)"যেন আপনি স্পষ্টভাবে গ্লোব্বিং এবং প্রসারণ চান না।
রেক্সকোগিটানস

2
আরও একটি সামান্য পার্থক্য: $(…)কোনও চলমান নিউলাইনটি কেটে ফেলা এবং তারপরে echoএটি আবার যুক্ত করুন। সুতরাং echo "$(printf %s 'a')" | xxdবিভিন্ন আউটপুট দেয় printf %s 'a' | xxd
ডারোবার্ট

1
আপনি ভুলে যাবেন না যে কিছু আজ্ঞা ( lsউদাহরণস্বরূপ) স্ট্যান্ডার্ড আউটপুট কনসোল কিনা তা নির্ভর করে ভিন্নভাবে কাজ করে; সুতরাং ls | catএকই lsকরে না। এবং অবশ্যই echo $(ls)ভিন্ন চেয়ে কাজ করবে ls
মার্টিন রোজেনউ

@ রুসলান উত্তর এখন সম্প্রদায় উইকি। আপনার উইকিটিতে আমি আপনার দরকারী মন্তব্য যুক্ত করেছি। ধন্যবাদ.
কামিল ম্যাকিয়েরোভস্কি

5

আরেকটি পার্থক্য: সাব-শেল প্রস্থান কোডটি হারিয়ে গেছে, সুতরাং এর প্রস্থানের প্রস্থান কোডটি echoপুনরুদ্ধার করা হবে।

> stuff() { return 1
}
> stuff; echo $?
1
> echo $(stuff); echo $?
0

3
সুপার ব্যবহারকারীকে স্বাগতম! আপনি যে পার্থক্যটি প্রদর্শন করছেন তা ব্যাখ্যা করতে পারেন ? ধন্যবাদ
বার্তিব

4
আমি বিশ্বাস করি যে এটি দেখায় যে রিটার্ন কোডটি কোনও এক সম্পাদকের পরিবর্তে (জন্য ) $?এর রিটার্ন কোড হবে । ফাংশন (প্রস্থান কোড), কিন্তু এটা সেট "0" থেকে ফেরত কোড নির্বিশেষে । এখনও উত্তরে থাকা উচিত। echoecho $(stuff)returnstuffstuffreturn 1echostuff
ইসমাইল মিগুয়েল

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