ব্যাশে, পাইপের পরে পড়া মান নির্ধারণ করে না


22

সম্পাদনা করুন: মূল শিরোনামটি ছিল "ব্যাশে পড়া ব্যর্থ"

Ksh সহ আমি মানগুলি পৃথক করার সুবিধাজনক উপায় হিসাবে পঠনটি ব্যবহার করছি:

$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a 
2 1
$

তবে এটি ব্যাশে ব্যর্থ:

$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a 

$

ম্যান পেজে আমি কোনও কারণ খুঁজে পাইনি কেন এটি ব্যর্থ হয়, কোনও ধারণা?


2
এটি গ্রেগের বাশ FAQ এর 024 পৃষ্ঠায় আলোচনা করা হয়েছে (কিছুটা অস্পষ্টভাবে) ।
স্কট

উত্তর:


27

bash একটি সাব-শেল প্রসঙ্গে পাইপলাইনের ডানদিকে চালিত করে , সুতরাং ভেরিয়েবলগুলিতে পরিবর্তন (যা যা readকরে) সংরক্ষণ করা হয় না - কমান্ডের শেষে সাব-শেল করলে তারা মারা যায়।

পরিবর্তে, আপনি প্রক্রিয়া বিকল্প ব্যবহার করতে পারেন :

$ read a b dump < <(echo 1 2 3 4 5)
$ echo $b $a
2 1

এই ক্ষেত্রে, readআমাদের প্রাথমিক শেলের মধ্যে চলছে, এবং আমাদের আউটপুট-উত্পাদনকারী কমান্ড সাব-শেলের মধ্যে চলে। <(...)সিনট্যাক্স সৃষ্টি একটি subshell এবং একটি নল, যা আমরা ইনপুট মধ্যে পুনর্নির্দেশ তার আউটপুট সংযোগ readসাধারণ সঙ্গে <অপারেশন । কারণ readআমাদের মূল শেলটিতে ভেরিয়েবলগুলি সঠিকভাবে সেট করা আছে।

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

read a b dump <<<"1 2 3 4 5"

আমি ধরে নিচ্ছি এর চেয়ে আরও অনেক কিছু আছে, তবে এটি না থাকলে এটি আরও ভাল বিকল্প।


3
বা এমনকি read a b dump <<< '1 2 3 4 5'
চোরোবা

সকলকে ধন্যবাদ, বিটিডব্লু আমি লক্ষ করেছি যে এমকেএস (সাইগউইন-এ) বাশের মতো একই কাজ করছে।
ইমানুয়েল

@ মিশেল হোমার ভাল ব্যাখ্যা! আমি অন্য একটা উদাহরণ যে পাইপলাইন প্রতিটি কমান্ড নিজের subshell চালানোর ব্যাখ্যা করতে পারে পাওয়া যায়নি: cat /etc/passwd | (read -r line ; echo $line)। কিন্তু পরবর্তী echoকয়েক $lineযা কারণ মান ঠিক মধ্যে প্রথম বন্ধনী (subshell) অস্তিত্ব ছিল, পর্দায় পাইপলাইন করা কিছুই নেই। আশা করি, এটি কাউকে সাহায্য করে।
ইউরিজ গনচরুক

17

এটি আপনারা যে দুর্ভাগ্যজনক তাত্পর্যকে পর্যবেক্ষণ করছেন তার দিকে পরিচালিত করে এবং আচরণ উভয়কেই অনুমতি দেয় এটি একটি bashত্রুটি নয় ।POSIXbashksh

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_12

অতিরিক্তভাবে, মাল্টি-কমান্ড পাইপলাইনের প্রতিটি কমান্ড সাব-শেল পরিবেশে থাকে; এক্সটেনশন হিসাবে, তবে, পাইপলাইনের যে কোনও বা সমস্ত কমান্ড বর্তমান পরিবেশে কার্যকর করা যেতে পারে। অন্যান্য সমস্ত কমান্ড বর্তমান শেল পরিবেশে কার্যকর করা হবে।

তবে এর সাথে bash 4.2এবং আরও নতুন, আপনি lastpipeপ্রত্যাশিত ফলাফল পেতে নন ইন্টারেক্টিভ স্ক্রিপ্টগুলিতে বিকল্পটি সেট করতে পারেন , যেমন:

#!/bin/bash

echo 1 2 3 4 5 | read a b dump
echo before: $b $a 
shopt -s lastpipe
echo 1 2 3 4 5 | read a b dump
echo after: $b $a 

আউটপুট:

before:
after: 2 1

1
"শেষের পাইপ" তথ্যের জন্য +1 আপনাকে ধন্যবাদ। বিলম্বের জন্য দুঃখিত
এমমানুয়েল

1
সমস্যাটি lastpipeহ'ল এটি অন্যান্য শেলগুলিতে কাজ করে না (যেমন ড্যাশ)। যে subshell সবকিছু চলমান এই পোর্টেবল সংক্ষিপ্ত করার কোন উপায় আছে মূলত দেখতে stackoverflow.com/questions/36268479/...
anarcat

1
@ আনারকাট এটি সঠিক তবে এখানে জিজ্ঞাসা করা প্রশ্নটি ছিল বাশ সম্পর্কে।
jlliagre

@ আনারকাট: এটি ভবিষ্যতে পরিবর্তিত হতে পারে যেহেতু অন্য কারণের জন্য পসিএক্স পরিবর্তন করার ইচ্ছা রয়েছে ( পিআইপিই স্থিতি) এখানে দেখুন: unix.stackexchange.com/questions/476834/… অন্যান্য শেল পরিবর্তন করা তুচ্ছ নয়, আমাকে কয়েক মাস সময় লেগেছে আধুনিক ksh এর দ্রুত আচরণ বাস্তবায়নের জন্য বোর্ন শেল (বোশ) এ পার্সার এবং ইন্টারপেটর পুনর্লিখন করা।
ছদ্মবেশে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.