পাইপে আউটপুট এবং বাশ-এ প্রস্থান স্থিতি


420

আমি ব্যাশ দীর্ঘ চলমান কমান্ড প্রয়োগ করতে চান, এবং উভয় ক্যাপচার তার প্রস্থান স্থিতি এবং Tee তার আউটপুট।

সুতরাং আমি এটি করি:

command | tee out.txt
ST=$?

সমস্যাটি হ'ল ভেরিয়েবল এসটি teeকমান্ডের নয় এবং প্রস্থান স্থিতি ক্যাপচার করে । আমি কীভাবে এটি সমাধান করতে পারি?

নোট করুন যে কমান্ডটি দীর্ঘ সময় ধরে চলছে এবং পরে এটি দেখার জন্য আউটপুটটিকে কোনও ফাইলে ডাইরেক্ট করা আমার পক্ষে ভাল সমাধান নয়।


1
[["" $ {পিপেষ্টাস্টাস [@]} "= ~ [^ 0 \]]] && প্রতিধ্বনি" মিল - ত্রুটি পাওয়া গেছে "|| প্রতিধ্বনি - "কোনও মিল নেই - সমস্ত ভাল" এটি অ্যারের সমস্ত মান একবারে পরীক্ষা করবে এবং যদি পাইপের কোনও মান মান শূন্য না হয় তবে ত্রুটি বার্তা দেবে। পাইপযুক্ত পরিস্থিতিতে ত্রুটি সনাক্ত করার জন্য এটি একটি দুর্দান্ত দৃ general় সাধারণ সমাধান।
ব্রায়ান এস উইলসন

উত্তর:


519

একটি অভ্যন্তরীণ ব্যাশ ভেরিয়েবল বলা হয় $PIPESTATUS; এটি এমন একটি অ্যারে যা আপনার কমান্ডের পূর্বের অগ্রভাগের পাইপলাইনে প্রতিটি কমান্ডের প্রস্থান স্থিতি রাখে।

<command> | tee out.txt ; test ${PIPESTATUS[0]} -eq 0

অথবা অন্য একটি বিকল্প যা অন্যান্য শেলগুলির সাথেও কাজ করে (যেমন zsh) হ'ল পাইপফেল সক্ষম করা:

set -o pipefail
...

কিছুটা আলাদা সিনট্যাক্সের কারণে প্রথম বিকল্পটি কাজ করে নাzsh


21
পাইপস্ট্যাটাস এবং পাইপফেইলের উদাহরণগুলির সাথে এখানে একটি ভাল ব্যাখ্যা রয়েছে: unix.stackexchange.com/a/73180/7453
slm

18
দ্রষ্টব্য: IP পাইপস্ট্যাটাস [0] পাইপে প্রথম কমান্ডের প্রস্থান স্থিতি রাখে, $ পিপেষ্টাস্টাস [1] দ্বিতীয় কমান্ডের প্রস্থান স্থিতি এবং এই জাতীয় কিছু।
সরল ব্যবহারকারী

18
অবশ্যই, আমাদের এটি মনে রাখতে হবে যে এটি বাশ-নির্দিষ্ট: যদি আমি (উদাহরণস্বরূপ) আমার অ্যান্ড্রয়েড ডিভাইসে বুসিবক্সের "sh" বাস্তবায়নটি চালানোর জন্য কোনও স্ক্রিপ্ট লিখতাম বা অন্য কোনও "sh" ব্যবহার করে অন্য কোনও এম্বেড প্ল্যাটফর্মে লিখতাম বৈকল্পিক, এটি কাজ করবে না।
আসফান্দ কাজী

4
অচিহ্নযুক্ত পরিবর্তনশীল প্রসারণ সম্পর্কে উদ্বিগ্নদের জন্য: প্রস্থান স্থিতি সবসময় বাশ -এ 8-বিট পূর্ণসংখ্যার স্বাক্ষরযুক্ত নয় , সুতরাং এটিকে উদ্ধৃত করার দরকার নেই। এটি সাধারণত ইউনিক্সের অধীনেও থাকে, যেখানে প্রস্থান স্থিতিটি 8-বিটকে স্পষ্টভাবে সংজ্ঞায়িত করা হয় এবং এটি পসিক্স নিজেই স্বাক্ষরবিহীন বলে ধরে নেওয়া হয়, যেমন এর যৌক্তিক অবজ্ঞা সংজ্ঞায়িত করার সময় ।
প্যালেক

3
আপনি ব্যবহার করতে পারেন exit ${PIPESTATUS[0]}
চৌওরান

142

ব্যাশ ব্যবহার set -o pipefailকরা সহায়ক

পাইপফেইল: পাইপলাইনের রিটার্ন মান হ'ল শূন্য-বিহীন স্থিতি সহ প্রস্থান করার জন্য শেষ কমান্ডের স্থিতি, বা শূন্য-বিহীন স্থিতি সহ কোনও কমান্ড উপস্থিত না হলে শূন্য হয় zero


23
আপনি যদি পুরো স্ক্রিপ্টের পাইপফেইল সেটিংসটি পরিবর্তন করতে না চান তবে আপনি কেবল স্থানীয়ভাবে বিকল্পটি সেট করতে পারেন:( set -o pipefail; command | tee out.txt ); ST=$?
জান

7
@ জাআন এটি একটি সাবস্কেল চালাবে। যদি আপনি এটি এড়াতে চান, আপনি set -o pipefailআদেশটি করতে পারেন এবং তারপরে অবিলম্বে set +o pipefailবিকল্পটি আনসেট করার জন্য করতে পারেন।
লিনাস আরভার

2
দ্রষ্টব্য: প্রশ্ন পোস্টারটি পাইপের "জেনারেল প্রস্থান কোড" চায় না, তিনি 'কমান্ডের' রিটার্ন কোড চান। সঙ্গে -o pipefailতিনি যদি নল ব্যর্থ জানতে চাই, কিন্তু যদি উভয় 'কম্যান্ড' এবং 'টী বর্ণের নাম' ব্যর্থ, সে টী বর্ণের নাম 'থেকে প্রস্থান কোড পাবে।
t0r0X

@ লিনাসআরভার যে প্রস্থানটি সফল হবে তার একটি নিষ্ক্রিয় কোডটি কী সাফ করবে না?
carlin.scott 0

126

বোবা সমাধান: নামযুক্ত পাইপের মাধ্যমে তাদের সংযুক্ত করা হচ্ছে (এমকেফিফো)। তারপর কমান্ড দ্বিতীয় চালানো যেতে পারে।

 mkfifo pipe
 tee out.txt < pipe &
 command > pipe
 echo $?

20
এটি এই প্রশ্নের একমাত্র উত্তর যা সাধারণ ইউনিক্স শেলের জন্যও কাজ করে । ধন্যবাদ!
জেমস থমাসমুন 1979

3
@ ডেভ কেনেডি: বোবা যেমন "স্পষ্টত, বাশ বাক্য
গঠনের

10
আপনার যখন ব্যাশের অতিরিক্ত সামর্থ্যের সুবিধা রয়েছে তখন ব্যাশ উত্তরগুলি আরও মার্জিত হয়, তবে এটি আরও ক্রস প্ল্যাটফর্ম সমাধান। এটি এমন একটি বিষয় যা সাধারণভাবে চিন্তা করার মতো কারণ যে কোনও সময় আপনি দীর্ঘমেয়াদী কমান্ড করছেন কোনও নাম পাইপ প্রায়শই সবচেয়ে নমনীয় উপায় way এটি লক্ষণীয় যে কয়েকটি সিস্টেমে নেই mkfifoএবং পরিবর্তে mknod -pযদি আমার সঠিক মনে থাকে তবে প্রয়োজন হতে পারে ।
হারাভিক্ক

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

1
যদি কারও সাথে সমস্যা হয় mkfifoবা mknod -p: আমার ক্ষেত্রে পাইপ ফাইল তৈরির যথাযথ আদেশ ছিল mknod FILE_NAME p
করোল গিল

36

একটি অ্যারে রয়েছে যা আপনাকে পাইপে প্রতিটি কমান্ডের প্রস্থান স্থিতি দেয়।

$ cat x| sed 's///'
cat: x: No such file or directory
$ echo $?
0
$ cat x| sed 's///'
cat: x: No such file or directory
$ echo ${PIPESTATUS[*]}
1 0
$ touch x
$ cat x| sed 's'
sed: 1: "s": substitute pattern can not be delimited by newline or backslash
$ echo ${PIPESTATUS[*]}
0 1

26

এই সমাধানটি ব্যাশ নির্দিষ্ট বৈশিষ্ট্য বা অস্থায়ী ফাইলগুলি ব্যবহার না করেই কাজ করে। বোনাস: শেষে প্রস্থান স্থিতি আসলে একটি প্রস্থান স্থিতি এবং কোনও ফাইলে কিছু স্ট্রিং নয়।

পরিস্থিতি:

someprog | filter

আপনি থেকে প্রস্থান স্থিতি someprogএবং আউটপুট চান filter

এখানে আমার সমাধান:

((((someprog; echo $? >&3) | filter >&4) 3>&1) | (read xs; exit $xs)) 4>&1

echo $?

দেখা unix.stackexchange.com একই প্রশ্নের জন্য আমার উত্তর একটি বিস্তারিত ব্যাখ্যা এবং subshells এবং কিছু আদেশ সহকারে ছাড়া একটি বিকল্প।


20

একত্রিত করে PIPESTATUS[0]এবং exitসাবসেলে কমান্ড কার্যকর করার ফলাফলের মাধ্যমে আপনি সরাসরি আপনার প্রাথমিক কমান্ডের রিটার্ন মানটি অ্যাক্সেস করতে পারেন:

command | tee ; ( exit ${PIPESTATUS[0]} )

এখানে একটি উদাহরণ:

# the "false" shell built-in command returns 1
false | tee ; ( exit ${PIPESTATUS[0]} )
echo "return value: $?"

তোমাকে দিবে:

return value: 1


4
ধন্যবাদ, এটি আমাকে কনস্ট্রাক্টটি ব্যবহার করার অনুমতি দিয়েছে: VALUE=$(might_fail | piping)যা মাস্টার শেলের মধ্যে পিপিসট্যাটাস সেট করে না তবে এটির ত্রুটিযুক্ত সেট সেট করবে। ব্যবহার করে: VALUE=$(might_fail | piping; exit ${PIPESTATUS[0]})আমি চাই আমি চাই
ভাইব

@বাব, সিনট্যাক্সটি দেখতে বেশ সুন্দর লাগছে তবে আপনার প্রসঙ্গে 'পাইপিং' বলতে কী বোঝায় তাতে আমি বিভ্রান্ত? কেবল সেখানেই কেউ 'টি' করবে বা জোর_ফোঁটের আউটপুটটিতে যা কিছু প্রক্রিয়াজাত করবে? TY!
অ্যানি দ্য অ্যাজিল

1
আমার উদাহরণে অ্যানিএইগাইল 'পাইপিং' হ'ল আদেশগুলি যা আপনি যেটি থেকে আরআরএলভিএল দেখতে চান তা বোঝায় না। উদাহরণস্বরূপ: 'টি', 'গ্রেপ', 'সেড', ... এর যে কোনও একটি বা পাইপযুক্ত সংমিশ্রণটি ... এটি এতটা অস্বাভাবিক নয় যে এই পাইপিং কমান্ডগুলি মূলের বৃহত আউটপুট বা লগ আউটপুট থেকে তথ্য বিন্যাস বা নিষ্কাশন করতে বোঝায় কমান্ড: আপনি তারপরে মূল কমান্ডের ভুল (যার জন্য আমি 'উদাহরণস্বরূপ' জোর_ফেইল 'বলেছি) এর প্রতি আরও আগ্রহী কিন্তু আমার সম্পূর্ণ বিন্যাস ব্যতীত শেষ পাইপ কমান্ডের এরলভেলটি ফিরে আসে যা এখানে অর্থহীন। এটা কি পরিষ্কার?
vaab

command_might_fail | grep -v "line_pattern_to_exclude" || exit ${PIPESTATUS[0]}ক্ষেত্রে টি না হলেও
গ্রেপ

12

সুতরাং আমি লেসমানার মতো একটি উত্তর অবদান রাখতে চেয়েছিলাম, তবে আমি মনে করি আমার সম্ভবত কিছুটা সহজ এবং কিছুটা সুবিধাজনক খাঁটি-বোর্ন শেল সমাধান:

# You want to pipe command1 through command2:
exec 4>&1
exitstatus=`{ { command1; printf $? 1>&3; } | command2 1>&4; } 3>&1`
# $exitstatus now has command1's exit status.

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

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

ম্যাজিকের চূড়ান্ত বিটটি হ'ল প্রথমটি exec 4>&1আমরা পৃথক কমান্ড হিসাবে করি - এটি বাহ্যিক শেলের স্টডআউটটির অনুলিপি হিসাবে ফাইল বর্ণনাকারী 4 খুলবে। কমান্ড প্রতিস্থাপন স্ট্যান্ডার্ডে যা লেখা আছে তার ভিতরে থাকা কমান্ডের দৃষ্টিকোণ থেকে এটি ক্যাপচার করবে - তবে যেহেতু কমান্ড 2 এর আউটপুট বর্ণনাকারী 4 ফাইল করতে চলেছে, কমান্ড প্রতিস্থাপনের ক্ষেত্রে কমান্ড প্রতিস্থাপন এটি ক্যাপচার করে না - তবে একবার এটি কমান্ড প্রতিস্থাপনের "আউট" পায় এটি কার্যকরভাবে এখনও স্ক্রিপ্টের সামগ্রিক ফাইল বর্ণনাকারী 1-এ চলছে।

( exec 4>&1এটি একটি পৃথক কমান্ড হতে হবে কারণ আপনি যখন কমান্ড সাবস্টিটিউশনের অভ্যন্তরে কোনও ফাইল বর্ণনাকারীর কাছে লেখার চেষ্টা করেন তখন প্রচলিত শেলগুলি এটি পছন্দ করে না, এটি "বহিরাগত" কমান্ডে খোলা হয় যা বিকল্পটি ব্যবহার করছে So সুতরাং এটি হ'ল এটি করার সহজতম পোর্টেবল উপায়))

আপনি এটিকে কম প্রযুক্তিগত এবং আরও কৌতুকপূর্ণ উপায়ে দেখতে পারেন, যেমন কমান্ডের আউটপুটগুলি একে অপরকে লিফফ্রোগ করছে: কমান্ড 1 তে কমান্ড 1 পাইপস, তারপরে প্রিন্টফের আউটপুট কমান্ড 2 এর উপরে লাফ দেয় যাতে কমান্ড 2 এটি ধরে না এবং তারপরে কমান্ড 2 এর আউটপুট কমান্ড প্রতিস্থাপনের বাইরে চলে যায় ঠিক একই সময়ে প্রিন্টফ জমিদার হিসাবে ক্যাপচার করার জন্য সময় নেয় যাতে এটি ভেরিয়েবলের সমাপ্ত হয়, এবং কমান্ড 2 এর আউটপুট তার আনন্দের পথে স্ট্যান্ডার্ড আউটপুটে লেখা হয়, ঠিক যেমন একটি সাধারণ পাইপে

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

ক্যাভিয়েটস লেসমানার উল্লেখ অনুসারে, সম্ভবত কমান্ড 1 কোনও সময় ফাইল বর্ণনাকারী 3 বা 4 ব্যবহার করে শেষ করবে, যাতে আরও দৃ rob় হয়, আপনি এটি করতে পারেন:

exec 4>&1
exitstatus=`{ { command1 3>&-; printf $? 1>&3; } 4>&- | command2 1>&4; } 3>&1`
exec 4>&-

মনে রাখবেন যে আমি আমার উদাহরণে যৌগিক আদেশগুলি ব্যবহার করি তবে সাবশেলগুলি (এর ( )পরিবর্তে ব্যবহার { }করাও কার্যকর হবে, যদিও এটি সম্ভবত কম দক্ষ হতে পারে))

কমান্ডগুলি ফাইল প্রবর্তনকারী প্রক্রিয়া থেকে ফাইল বর্ণনাকারীদের উত্তরাধিকার সূত্রে প্রাপ্ত হয়, সুতরাং সম্পূর্ণ দ্বিতীয় লাইনে ফাইল বর্ণনাকারী চারটি উত্তরাধিকার সূত্রে প্রাপ্ত হয় এবং এরপরে যৌগিক কমান্ডটি 3>&1ফাইল বর্ণনাকারী তিনটি উত্তরাধিকার সূত্রে প্রাপ্ত হয়। সুতরাং এটি 4>&-নিশ্চিত করে যে অভ্যন্তরীণ যৌগ কমান্ডটি ফাইল বর্ণনাকারী চারটি 3>&-উত্তরাধিকার সূত্রে প্রাপ্ত হবে না এবং তিনটি ফাইল বর্ণনাকারীর অধিকারী হবে না, সুতরাং কমান্ড 1 একটি 'ক্লিনার', আরও মানক পরিবেশ পায় gets আপনি অভ্যন্তরের 4>&-পাশের পাশের অংশটিও সরিয়ে ফেলতে পারেন 3>&-, তবে আমি বুঝতে পারি কেন কেবল তার সুযোগটি যতটা সম্ভব সীমাবদ্ধ করা যায় না।

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


সুন্দর ব্যাখ্যা!
সেলুরવેদু

6

উবুন্টু এবং ডেবিয়ান, আপনি করতে পারেন apt-get install moreutils। এটিতে একটি ইউটিলিটি রয়েছে mispipeযা পাইপে প্রথম কমান্ডের প্রস্থান স্থিতি দেয়।


5
(command | tee out.txt; exit ${PIPESTATUS[0]})

@ সিওএডিআর এর উত্তরের বিপরীতে এটি প্রথম কমান্ডের আসল প্রস্থান কোডটি দেয় এবং কেবল 0 সাফল্যের জন্য নয় 127 ব্যর্থতার জন্য। তবে @ চাওরান যেমন উল্লেখ করেছেন আপনি কেবল কল করতে পারেন ${PIPESTATUS[0]}। তবে এটি গুরুত্বপূর্ণ যে সমস্ত ব্র্যাকেটে রাখা হয়।


4

ব্যাশের বাইরে, আপনি এটি করতে পারেন:

bash -o pipefail  -c "command1 | tee output"

এটি নিঞ্জা স্ক্রিপ্টগুলিতে উদাহরণস্বরূপ দরকারী যেখানে শেলটি প্রত্যাশিত /bin/sh


3

পাইপ কমান্ড ফিরে আসার সাথে সাথে পাইপস্ট্যাটাস [@] অবশ্যই একটি অ্যারেতে অনুলিপি করা উচিত। PIPESTATUS [@] এর যে কোনও পাঠ্য বিষয়বস্তুগুলি মুছে ফেলবে। আপনি যদি সমস্ত পাইপ কমান্ডের স্থিতি পরীক্ষা করার পরিকল্পনা করে থাকেন তবে এটি অন্য অ্যারেতে অনুলিপি করুন। "$?" "$ {পাইপস্ট্যাটাস [@]}" এর সর্বশেষ উপাদান হিসাবে একই মান, এবং এটি পড়লে মনে হয় এটি "$ {পাইপস্ট্যাটাস [@]।" ধ্বংস করে দিবে, তবে আমি এটি একেবারেই যাচাই করে নি।

declare -a PSA  
cmd1 | cmd2 | cmd3  
PSA=( "${PIPESTATUS[@]}" )

পাইপটি সাব-শেলের মধ্যে থাকলে এটি কাজ করবে না। এই সমস্যার সমাধানের জন্য, ব্যাকটিক কমান্ডে বাশ পাইপস্ট্যাটাসটি
দেখুন ?


3

প্লেইন ব্যাশে এটি করার সহজ উপায় হ'ল পাইপলাইনের পরিবর্তে প্রক্রিয়া বিকল্প ব্যবহার করা । বিভিন্ন পার্থক্য রয়েছে, তবে আপনার ব্যবহারের ক্ষেত্রে এগুলি সম্ভবত খুব বেশি গুরুত্বপূর্ণ নয়:

  • পাইপলাইন চালানোর সময়, ব্যাশ সমস্ত প্রক্রিয়া শেষ না হওয়া পর্যন্ত অপেক্ষা করে।
  • Ctrl-C ব্যাশে পাঠানো কেবল পাইপলাইনের সমস্ত প্রক্রিয়া মুছে ফেলবে, কেবল প্রধান নয়।
  • pipefailবিকল্প এবং PIPESTATUSপরিবর্তনশীল প্রক্রিয়া প্রতিকল্পন অপ্রাসঙ্গিক হয়।
  • সম্ভবত আরও

প্রক্রিয়া প্রতিস্থাপনের সাথে, ব্যাশ কেবল প্রক্রিয়া শুরু করে এবং এটি সম্পর্কে ভুলে যায়, এটি এমনকি দৃশ্যমান নয় jobs

পার্থক্যগুলি একদিকে উল্লেখ করেছেন consumer < <(producer)এবং producer | consumerএটি মূলত সমতুল্য।

আপনি যদি কোনটি "প্রধান" প্রক্রিয়া হ'ল ফ্লিপ করতে চান, আপনি কেবলমাত্র আদেশগুলি এবং বিকল্পটির দিকটি ফ্লিপ করুন producer > >(consumer)। আপনার ক্ষেত্রে:

command > >(tee out.txt)

উদাহরণ:

$ { echo "hello world"; false; } > >(tee out.txt)
hello world
$ echo $?
1
$ cat out.txt
hello world

$ echo "hello world" > >(tee out.txt)
hello world
$ echo $?
0
$ cat out.txt
hello world

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


1

খাঁটি শেল দ্রবণ:

% rm -f error.flag; echo hello world \
| (cat || echo "First command failed: $?" >> error.flag) \
| (cat || echo "Second command failed: $?" >> error.flag) \
| (cat || echo "Third command failed: $?" >> error.flag) \
; test -s error.flag  && (echo Some command failed: ; cat error.flag)
hello world

এবং এখন দ্বিতীয় catদ্বারা প্রতিস্থাপিত false:

% rm -f error.flag; echo hello world \
| (cat || echo "First command failed: $?" >> error.flag) \
| (false || echo "Second command failed: $?" >> error.flag) \
| (cat || echo "Third command failed: $?" >> error.flag) \
; test -s error.flag  && (echo Some command failed: ; cat error.flag)
Some command failed:
Second command failed: 1
First command failed: 141

দয়া করে মনে রাখবেন প্রথম বিড়ালটিও ব্যর্থ হয়েছে, কারণ এটি স্টডআউট এতে বন্ধ হয়ে যায়। লগে ব্যর্থ কমান্ডগুলির ক্রম এই উদাহরণে সঠিক, তবে এটির উপর নির্ভর করবেন না।

এই পদ্ধতিটি পৃথক কমান্ডগুলির জন্য stdout এবং stderr ক্যাপচার করার অনুমতি দেয় যাতে আপনি এরপরে কোনও ত্রুটি দেখা দিলে লগ ফাইলে ডাম্প করতে পারেন বা কোনও ত্রুটি না হলে এটি মুছুন (ডিডির আউটপুট যেমন)।


1

@ ব্রায়ান-এস-উইলসনের উত্তরের ভিত্তিতে; এই বাশ সহায়ক সহায়ক:

pipestatus() {
  local S=("${PIPESTATUS[@]}")

  if test -n "$*"
  then test "$*" = "${S[*]}"
  else ! [[ "${S[@]}" =~ [^0\ ] ]]
  fi
}

এইভাবে ব্যবহৃত:

1: get_bad_things অবশ্যই সফল হবে, তবে এটির কোনও আউটপুট তৈরি করা উচিত নয়; তবে আমরা আউটপুট দেখতে চাই যা এটি উত্পাদন করে

get_bad_things | grep '^'
pipeinfo 0 1 || return

2: সমস্ত পাইপলাইন সফল হতে হবে

thing | something -q | thingy
pipeinfo || return

1

ব্যাশের বিশদ অনুসন্ধানের পরিবর্তে বাহ্যিক কমান্ডটি ব্যবহার করা কখনও কখনও সহজ এবং পরিষ্কার হতে পারে। পাইপলাইন , ন্যূনতম প্রক্রিয়া স্ক্রিপ্টিং ল্যাংগুয়েজ এক্সিক্লিন থেকে , দ্বিতীয় কমান্ড * এর রিটার্ন কোড সহ প্রস্থান করে, ঠিক যেমন shপাইপলাইন করে, তবে এর বিপরীতে shএটি পাইপের দিকটি উল্টে দেয়, যাতে আমরা প্রযোজকের রিটার্ন কোডটি ক্যাপচার করতে পারি প্রক্রিয়া (নীচে সমস্ত shকমান্ড লাইনে রয়েছে, তবে সহ)execline ইনস্টল করা আছে):

$ # using the full execline grammar with the execlineb parser:
$ execlineb -c 'pipeline { echo "hello world" } tee out.txt'
hello world
$ cat out.txt
hello world

$ # for these simple examples, one can forego the parser and just use "" as a separator
$ # traditional order
$ pipeline echo "hello world" "" tee out.txt 
hello world

$ # "write" order (second command writes rather than reads)
$ pipeline -w tee out.txt "" echo "hello world"
hello world

$ # pipeline execs into the second command, so that's the RC we get
$ pipeline -w tee out.txt "" false; echo $?
1

$ pipeline -w tee out.txt "" true; echo $?
0

$ # output and exit status
$ pipeline -w tee out.txt "" sh -c "echo 'hello world'; exit 42"; echo "RC: $?"
hello world
RC: 42
$ cat out.txt
hello world

ব্যবহার pipelineউত্তর ব্যবহৃত ব্যাশ প্রক্রিয়া প্রতিকল্পন যেমন স্থানীয় ব্যাশ পাইপলাইনগুলি একই পার্থক্য রয়েছে # 43972501

* pipelineযদি কোনও ত্রুটি না ঘটে তবে প্রকৃতপক্ষে বাইরে বেরোবেন না। এটি দ্বিতীয় কমান্ডে কার্যকর করে, সুতরাং এটি দ্বিতীয় কমান্ডটি ফিরে আসে।

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