কেন শেল কমান্ড সাবস্টিটিউশন একটি পিছনে থাকা নতুন লাইনের চরকে আপত্তি করে?


25

নীচের উদাহরণ অনুসারে, এবং আমার সাম্প্রতিক প্রশ্ন অনুসারে ব্যাশে, নতুন লাইনের চরটি কোথায় গেল? , আমি জানতে চাই "কেন" এটি ঘটে

  x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p 
# Output is: 610a62 
# The trailing newline from the 'echo' command
#   has been "deleted" by Command Substitution

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


উত্তর:


22

কারণ শেলটি মূলত একটি সম্পূর্ণ প্রোগ্রামিং ভাষা হওয়ার উদ্দেশ্যে নয়।

\nকিছু কমান্ড আউটপুট থেকে ট্রেলিং অপসারণ করা বেশ কঠিন । যাইহোক, প্রদর্শনের উদ্দেশ্যে, প্রায় সমস্ত কমান্ড তাদের আউটপুটটি সমাপ্ত করে \n, সুতরাং ... যখন আপনি অন্য কমান্ডে এটি ব্যবহার করতে চান তখন এটিকে সরানোর একটি সহজ উপায় থাকতে হবে। $()নির্মাণের সাথে স্বয়ংক্রিয় অপসারণই ছিল বেছে নেওয়া সমাধান।

সুতরাং, সম্ভবত আপনি এই প্রশ্নের উত্তর হিসাবে গ্রহণ করবেন:

\nনিম্নলিখিত কমান্ডটিতে স্বয়ংক্রিয়ভাবে এটি করা না হলে আপনি অনুসরণ করতে সরানোর কোনও সহজ উপায় খুঁজে পেতে পারেন ?

> echo The current date is "$(date)", have a good day!

নোট করুন যে বিন্যাসকরণের তারিখগুলিতে প্রদর্শিত হতে পারে এমন দ্বিগুণ স্থানের স্মैशিং রোধ করতে উদ্ধৃতি আবশ্যক।


1
আপনি যা বলেন তা যদি সত্য হয় তবে আমি একেবারে হতবাক হয়ে যাব। যদি একটি shoptআপনার বর্ণনা ডিফল্ট আচরণ পরিবর্তন করার জন্য, তারপর আমি আবার খুশি হবেন ... আমি এটা কঠিন মনে করেন যে ব্যাশ / লিনাক্স / ইউনিক্স হিসাবে "stdout- এ ক্যাপচার" শুধু কারণ এই ধরনের একটি সমালোচনামূলক ফাংশন দূষিত করা হবে পেতে dateনেই 'without n' অপশনটি সহ / ছাড়াই ... সুস্পষ্ট সমাধানটি হ'ল বাশ (বা অন্য শেল) এর shoptজন্য এটি রয়েছে ... আপনি কোনওটি জানেন? .. এবং আপনার কি এমন কোনও রেফারেন্স লিঙ্ক রয়েছে যা এই বিচ্ছিন্নতার কারণগুলি সম্পর্কে আলোচনা করে? ... এবং কেন date\ n বিকল্প নেই .. এটি করা উচিত!
পিটার.ও

2
কমান্ডের বিকল্পগুলি ১৯৯ 1979 সালে ইউনিক্সের "সপ্তম সংস্করণ" বর্ন শেলের প্রথম সংস্করণে উপস্থিত হয়েছিল । এটি ইতিমধ্যে একটি বড় বিপ্লব হয়েছিল এবং আমার ধারণা (আমি জন্মগ্রহণ করি নি) যে '\ n' অনুসরণ করে রাখার বিষয়ে কেউ পাত্তা দেয় না। হ্যাঁ, আপনি পড়তে পারেন র manpage 10min কম সময়ে, এবং এটি কিছুই কমান্ড প্রতিকল্পন সম্পর্কে তখন পর্যন্ত পরিবর্তিত হয়েছে বলে মনে হয়। পছন্দসই $()বিকল্প সিনট্যাক্স ব্যতীত ।
স্টাফেন গিমেনেজ

ধন্যবাদ .. আমি ভেবেছিলাম এটি কোনও উত্তরাধিকারসূত্রে সমস্যা হতে পারে এবং এটি অবশ্যই সত্যিকার অর্থেই রূপ নিচ্ছে যে আমি আরও ভালভাবে আমার কমান্ড সাবস্টিটিউশনগুলি দেখতে শুরু করেছি। আজ অবধি আমি নিশ্চয়ই ডানা বেঁধে প্রার্থনা করেছি .. এমন কিছু "রহস্যজনক ঘটনা" যাদের আমি মুখোমুখি হয়েছি তা এখন বোধগম্য হতে শুরু করেছে :) ... সুতরাং আপনার "তারিখ" পোস্টের বিপরীত ক্ষেত্রে যদি, আমি আমার { echo -n "The current date is "; var="$(date; echo -e x)"; var="${var%x}"; echo -n "$var"; echo ", have a good day!"; }
ট্রেলিং

পিএস আমার উপরের মন্তব্যটি: অবশ্যই, dateকাজ করবে তবে আমি কেবল কোনও আদেশের dateউদাহরণ হিসাবে ব্যবহার করেছি ..
পিটার.ও

আপনার 'প্রশ্ন' তারিখ সম্পর্কে আমার বোঝার প্রতি প্রবল প্রমোট ছিল 'কেন' কমান্ড সাবস্টিউশন এটি কী করে, তাই এটি আমার প্রশ্নের 'সেরা' উত্তর ছিল ... এবং অবশ্যই আমার অন্যান্য উত্তরের উত্তরও দরকার ছিল ..
পিটার.ও

19

এটি স্ট্যান্ডার্ডের অংশ :

শেল নির্বাহ দ্বারা কমান্ড প্রতিকল্পন প্রসারিত হইবে কমান্ড একটি subshell পরিবেশে (দেখুন শেল এক্সেকিউশন এনভায়রনমেন্টের এবং কমান্ড প্রতিকল্পন (টেক্সট প্রতিস্থাপন) কমান্ড কমান্ড মান আউটপুট প্লাস এনক্লোজিং "$ ()" বা backquotes), অপসারণ প্রতিস্থাপনের শেষে এক বা একাধিক <নিউলাইন> এর ক্রম।

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


একটি দুর্দান্ত সংক্ষিপ্ত বিবরণ .. ধন্যবাদ .. এবং লিঙ্কগুলি অবশ্যই সহায়তা করেছে
পিটার.ও

4
স্ট্যান্ডার্ডটি এর মতো কারণ কারণ বোর্ন শেল এটি এবং এর পর থেকে প্রতিটি অন্যান্য শেল এটি করেছিল।
গিলস 21'10 এ 21

6

ঠিক আছে, এটা আমার জন্য বোধগম্য। সাধারণ কমান্ড আউটপুটে নিউ লাইনটি কেবল প্রথম স্থানে থাকে, যাতে কমান্ডটি একটি নতুন লাইনে সম্পূর্ণ হওয়ার পরে প্রম্পট উপস্থিত হয়। নিউলাইনটি বেশিরভাগ ক্ষেত্রে আসল আউটপুটের অংশ নয়, স্ক্রিনটি পরিষ্কার করার জন্য এটি রয়েছে। আপনি যখন কোনও কমান্ড থেকে আউটপুট পার্সিং করেন তখন শেষে লাইনটি সাধারণত ঝামেলা হয়। wcকমান্ড আউটপুট 2 টি পাঠ্য পাঠ করে কেন ? ওহ, এটি হয় না, এটি একটি নতুন লাইনের পরে আউটপুট দেয়। আপনি যখন বিশ্লেষণ wcকরবেন তখন আপনি 2 লাইন আউটপুট আছে এমনটি নিয়ে চিন্তিত হতে চান না - সত্যিকার অর্থেই নেই, কেবল একটি আছে।


@ আইটবিটটনি: আমার প্রশ্নটি কোনওভাবেই টার্মিনালের কিছু প্রদর্শন সম্পর্কিত নয় .. এটি বেশ সোজা এগিয়ে। যদি এখানে একটি নতুন লাইন প্রদর্শন করতে হয়, তবে এটি নতুন লাইনটি প্রদর্শন করবে .. এখানে প্রশ্নে \nমূল stdoutবিষয়টি হ'ল মূল স্ট্রিমের একটি হ'ল কমান্ড সাবস্টিটিউশন দ্বারা সরানো হবে। অর্থাত। আমার মূল তথ্যটি (খুব গুরুত্বপূর্ণ ডেটা) নতুন লাইনগুলি সরিয়ে ফেলেছে, এমনকি যখন ডেটা "কোটস" এ মোড়ানো থাকে। ওয়ার্ড স্প্লিটিং কীভাবে এবং কেন কাজ করে তা আমি যুক্তিসঙ্গতভাবে বুঝতে পারি, তবে কেন কমান্ড সাবস্টিটিউশনটি কেবলমাত্র নতুন লাইনে এবং কেবল অনুসরণীয় বিষয়গুলি স্ট্রিপ করে তা আমার কোনও ধারণা নেই ।
পিটার.ও

1
আপনি যা বলেছেন কিছুই কিছুই আমার দৃষ্টিভঙ্গি পরিবর্তন করে না। প্রায়শই না এটির চেয়ে বেশি, কোনও আউটপুটে চূড়ান্ত নিউলাইন হ'ল বিশুদ্ধরূপে প্রদর্শনের উদ্দেশ্যে, তথ্যের অংশ হিসাবে নয়।
এইটবিটটনি

আমি তোমার দৃশ্য সঙ্গে একমত, এবং ... সব বরাবর আছে হ্যাঁ আউটপুট শেষে সম্পর্কে newline হয় সুবিধার জন্য ... কিন্তু আমার সমস্যা যে সঙ্গে কিছুই করার আছে ... আমি জিজ্ঞাসা করছি কেন কমান্ড উপকল্পন জোরপূর্বক এটি অপসারণ নেই ? ... এটি দুটি ভিন্ন বিষয় .. হতে পারে আমার প্রশ্নটি হওয়া উচিত: কোনও কাজের ভিত্তিতে কোনও বিল্ট রয়েছে? । কারণ এই পেছনের পেছনে ডামি চর যোগ করে এই সমস্যাটির জন্য কোড করতে হবে! যদি আমি আছে ... আমি এটা করবো, কিন্তু এই প্রথমবার আমি ব্যাশ দ্বারা কোণঠাসা করে থাকেন (এবং আমি শক অবস্থায় আছি :) .. এটা এত এত ভাল করে ...
পিটার.ও

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

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

1

আমি একই ইস্যুতে চলছিলাম, এবং নীচের উদাহরণটি পেয়েছি। উদ্ধৃতিটি পরিস্থিতিটিকে সহায়তা করেছে বলে মনে হচ্ছে, কমপক্ষে এটি আমার পক্ষে হয়েছিল:

http://tldp.org/LDP/abs/html/commandsub.html

dir_listing=`ls -l`
echo $dir_listing     # unquoted

# Expecting a nicely ordered directory listing.

# However, what you get is:
# total 3 -rw-rw-r-- 1 bozo bozo 30 May 13 17:15 1.txt -rw-rw-r-- 1 bozo
# bozo 51 May 15 20:57 t2.sh -rwxr-xr-x 1 bozo bozo 217 Mar 5 21:13 wi.sh

# The newlines disappeared.


echo "$dir_listing"   # quoted
# -rw-rw-r--    1 bozo       30 May 13 17:15 1.txt
# -rw-rw-r--    1 bozo       51 May 15 20:57 t2.sh
# -rwxr-xr-x    1 bozo      217 Mar  5 21:13 wi.sh

2
এখানে যা ঘটছে তা এখানে। আসুন বলে একটি পরিবর্তনশীল আছে, $str, স্ট্রিং সম্বলিত "a b c"। আপনি পাস যদি $strকরতে echoউদ্ধৃতি (ছাড়া echo $str), echoপাবেন a, bএবং cপৃথক আর্গুমেন্ট হিসাবে তিন। আপনার শেলটি আর্গুমেন্টের মধ্যে থাকা সাদা স্পেসের বিষয়ে চিন্তা করে না। echoতারপরে সেই যুক্তিগুলি প্রতিটি পৃথক করে ফাঁক দিয়ে মুদ্রণ করবে, যাতে আপনি পান "a b c"। আপনি যদি ভেরিয়েবলটিকে echoচারপাশে ( echo "$str") এর কোট দিয়ে পাস করেন তবে শেল এটিকে একটি আর্গুমেন্ট হিসাবে দেখায় এবং echoএটিকে গ্রহণ করে, তাই শ্বেত স্থানটি ধসে পড়ে না। একই বিষয়টি নিউলাইনগুলিতে প্রযোজ্য।

1
মূল পোস্টারটি যে সমস্যাটি নিয়ে আসছে তা হ'ল তার আদেশগুলি অনুমান করা নতুন লাইনের (কেবলমাত্র শেষেরগুলি) অদৃশ্য হয়ে যাচ্ছে। -nপতাকাটি পাস না করে , echoতার আউটপুটে একটি ট্রেলিং নিউলাইন যুক্ত করে, সুতরাং আপনার উদাহরণের প্রতিধ্বনির দুটিই নতুন লাইনের পিছনে রয়েছে। তবে, আপনি চেষ্টা করলে echo -n $dir_listingবা echo -n "$dir_listing", আপনি দেখতে পাবেন যে কোনও অনুমানযোগ্য নতুন লাইন চারপাশে উদ্ধৃতি বা তার সাথে প্রিন্ট করা নেই $dir_listing, যা পরামর্শ দেয় যে সমস্যাটি কমান্ড প্রতিস্থাপনের ক্ষেত্রে।

2
শেল স্ক্রিপ্টিং সম্পর্কে শিখার জন্য tldp একটি খারাপভাবে পুরানো জায়গা। পরিবর্তে উউলেজ বাশ উইকির চেষ্টা করুন। mywiki.wooledge.org/BashGuide
ওয়াইল্ডকার্ড

-1

echo "hello "(উদ্ধৃতি ব্যতীত) কেন জায়গা গলগল করে? আইএফএস অক্ষরের মান শেল দ্বারা ডিলিমিটার হিসাবে দেখা যায়, অতএব, অনুবর্তী অক্ষরগুলি (যেটি কিছুতেই সীমানা ছাড়াই না) সরানো হচ্ছে। প্রশংসনীয় প্রতিস্থাপন হ'ল একটি সাব শেল মধ্যে প্রশংসাপত্র সম্পাদন করা সহজ, সুতরাং এটি একই যুক্তি অনুসরণ করে।


@ ফিলোমাথ: উভয়ের মাধ্যমে x="hello  "এবং x="hello     "যদি তাদের মাধ্যমে প্রদর্শিত হয় তবে তাদের সমস্ত চলমান স্থান হারাবে echo $x... তবে কমান্ড সাবস্টিটন-এর কেবলমাত্র শেষ লাইনটি হারিয়ে গেছে।
পিটার.ও

আশ্চর্যজনক, আমি আমার বাশে কোনও পার্থক্য দেখতে পাই না (এক্সএক্সডি দিয়ে যাচাই করা)
ফিলোমাথ

আমি কেবল এটির জন্য চেক করছি ... এটি সমস্ত ট্রেলিং করা নতুনলাইনগুলি সরিয়ে ফেলবে ... আমি যখন এই ধারণাটি পেয়েছিলাম তখন আমি আইএফএসের সাথে পরীক্ষা করছিলাম, সুতরাং আসুন এটি বাতিল করুন :) .. তবে প্রশ্নটি এখনও রয়ে গেছে ... এটি একটি মৌলিক অংশ শব্দ বিভাজন একটি একক স্থান একাধিক স্পেস ঘনীভূত, এবং সম্পূর্ণভাবে সামনের এবং হোয়াইটস্পেস trailing মুছে ফেলার জন্য .. আমি করতে পারেন যে বুঝি, কিন্তু আমি অবশ্যই বুঝতে পারছি না কেন, কমান্ড উপকল্পন সঙ্গে, এটা শুধুমাত্র রেখাচিত্রমালা \ N এবং সব হোয়াইটস্পেস (যেমন শব্দের বিভাজন সহ) এবং কেন কেবল শেষের শেষ? .. এবং সর্বোপরি: "কমান্ড সাবস্টিটিউশন" কেবলমাত্র আংশিকভাবে প্রতিস্থাপন করছে .. কেন?
পিটার.ও

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