একক পাইপযুক্ত কমান্ডের জন্য পাইপফেইল সেট করা হচ্ছে


19

আমাকে এর মতো নন-বেস স্ক্রিপ্ট (যথা পিএইচপি স্ক্রিপ্ট) থেকে বেশ কয়েকটি পাইপযুক্ত শেল কমান্ড প্রয়োগ করতে হবে:

command1 | command2 | command3

যাতে, যদি command1কোনও শূন্য-বহির্গমন কোডের সাথে ব্যর্থ হয় তবে একে অপরের কমান্ডও ব্যর্থ হয়। এতক্ষণ, আমি যা নিয়ে এসেছি তা হ'ল:

set -o pipefail && command1 | command2 | command3

এটি টার্মিনাল থেকে সূক্ষ্মভাবে চালিত হলেও, স্ক্রিপ্ট থেকে সম্পাদন করা হলে এটি তৈরি করে:

sh: 1: set: অবৈধ বিকল্প -o পাইপফেইল


এটি প্রদর্শিত হবে /bin/shনা set -o pipefail। এটি আসলে bashছদ্মবেশে রয়েছে, না এটি অন্যরকম শেল? যখন bashহিসাবে চালানো হয় /bin/sh, এটি গ্রহণ করে set -o pipefail?
জোনাথন লেফলার

@ জোনাথনলফলার যখন আমি /bin/sh set -o pipefailএটি চালায় তখন বলে /bin/sh: 0: Can't open set(একই জিনিসটি sudo)। আশা করি আমি এটি সঠিকভাবে পরীক্ষা করেছি। সিস্টেমটি উবুন্টু 12.
ডেসমন্ড হিউম

আপনার চেষ্টা করা দরকার /bin/sh -c "set -o pipefail"; যেমনটি ছিল, শেলটি বর্তমান ডিরেক্টরিটিতে বলা একটি স্ক্রিপ্ট কার্যকর করার চেষ্টা করছে setএবং এটি এটি খুঁজে পেল না।
জোনাথন লেফলার

@ জোনাথনলফলার /bin/sh -c "set -o pipefail"কাজ করছেন না, তবে bash -c "set -o pipefail"তা করে।
ডেসমন্ড হিউম

সুতরাং, আপনার সমস্যাটি হ'ল স্ক্রিপ্টটি চালিত হয় /bin/shযা স্বীকৃতি দেয় না set -o pipefail। ফলস্বরূপ, আপনার স্ক্রিপ্টটি /bin/bashপরিবর্তে চালিত হয়েছে তা নিশ্চিত করতে হবে /bin/sh। অথবা, যদি আপনি আত্মবিশ্বাসী, সাহসী - এবং সম্ভবত নির্বোধ - এটি বর্তমানে যে কোনও শেলের সাথে লিঙ্কযুক্ত /bin/shবা এর অনুলিপি /bin/bashপরিবর্তে একটি লিঙ্ক বা অনুলিপি হিসাবে পরিবর্তন করুন। আপনি যদি তা নিশ্চিত যে /bin/shহয় bash, তাহলে আপনি আচরণ যা ব্যবহার করছেন bashযখন হিসাবে চালানো দেখাবে না তা /bin/sh; bashহিসাবে ব্যবহার করুন bash
জোনাথন লেফলার

উত্তর:


18

বাশ কমান্ড লাইন থেকে pipefailপরে সেট হওয়া থেকে বাঁচতে আপনার সাবস্কেলটি আহ্বান করতে হবে :

$ (set -o pipefail && command1 | command2 | command3)

এটি pipefailবিকল্পের প্রভাবকে প্রথম বন্ধনী দ্বারা তৈরি করা সাব-শেল সীমাবদ্ধ করবে (...)

একটি বাস্তব উদাহরণ:

$ (set -o pipefail && false | true) && echo pipefail inactive || echo pipefail active
pipefail active

আপনার সাথে একটি স্পষ্ট শেল কল ব্যবহার করেন তাহলে -cবিকল্প আপনি হয় সঙ্গে একটি subshell প্রয়োজন হবে না, bashঅথবা একটি সঙ্গে shথেকে ওরফে bash:

$ bash -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active
$ sh -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active

যেহেতু আপনার বিকল্পটি shগ্রহণ করে না pipefail, তাই আমি ধরে নিতে হবে এটি হয় এটি বেশ কিছু পুরানো বা সংশোধিত সংস্করণ bashor বা এটি আসলে অন্য কোনও শেল সম্পূর্ণরূপে।


1
$প্রথম টুকরাটিতে কি কমান্ডের একটি অংশ এটি কেবল একটি শেল প্রম্পট? উভয় উপায়ে চেষ্টা করেছেন, বাস্তবে কাজ করেননি। bash -cপথ সবসময় কাজ করে, না খুব মার্জিত হউক না কেন ..
ডেসমন্ড হিউম

5

কেন এটি উপরে উল্লিখিত হয়নি তা নিশ্চিত নয় তবে এটি pipefailব্যবহার করে স্পষ্টতই আনসেট করা সম্ভব set +o pipefail

set -o pipefail
command1 | command2 | command3
set +o pipefail

যদি আপনি কোনও খণ্ডটি চালাচ্ছেন এবং pipefailইতিমধ্যে সেট সম্পর্কে অনিশ্চিত হয়ে থাকেন তবে আপনি পূর্বে প্রস্তাবিত সাবসেলের মাধ্যমে এটি ব্যবহার করতে পারেন:

# explicitly execute with pipefail set
(set -o pipefail ; command1 | command2 | command3 )
# explicitly execute with pipefail unset
(set +o pipefail ; command1 | command2 | command3 )

0

আপনি with (কমান্ড 1) combined এর সাথে মিলিত ব্যবহার করতে পারেন? :

a=$(echo "a")
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

"এবিসি" মুদ্রণ

a=$(ls unexitingDir)
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

মুদ্রণ ""।

"[$? -eq 0] &&" এর অর্থ হল যে পূর্ববর্তীটি সফল হলে কেবল নিম্নলিখিত আদেশটি কার্যকর করা হবে।

এটি আপনার প্রশ্নের উত্তর দেয় না তবে এটি আপনার সমস্যার সমাধান।


এর অর্থ কি এই যে আমি সর্বদা প্রতিটি কমান্ডের আউটপুট একটি ভেরিয়েবলের মধ্যে সঞ্চয় করতে পারি?
ডেসমন্ড হিউম

সর্বদা আমি জানি না তবে আমার সমাধানের সাথে হ্যাঁ আপনি যাবেন (যদি আপনার পরবর্তী কমান্ডের প্রয়োজন হয়)। আপনি কেবল লিখতে না command1 && command2 && command3
পারলে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.