শর্তাধীন পাইপলাইন


39

বলুন আমি নীচের পাইপলাইন পেয়েছি:

cmd1 < input.txt |\
cmd2 |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt

নির্দিষ্ট শর্তে আমি এবং এর cmd3মধ্যে একটি যোগ করতে চাই । কোনও অস্থায়ী ফাইলে সেমিডি 2 এর ফলাফল সংরক্ষণ না করে কি কোনও ধরনের শর্তসাপেক্ষ পাইপলাইন তৈরির উপায় আছে? আমি এরকম কিছু সম্পর্কে ভাবতে চাই:cmd2cmd4

cmd1 < input.txt |\
cmd2 |\
(${DEFINED}? cmd3 : cat ) |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt

উত্তর:


36

কেবল সাধারণ &&এবং ||অপারেটরগুলি:

cmd1 < input.txt |
cmd2 |
( [[ "${DEFINED}" ]] && cmd3 || cat ) |
cmd4 |
cmd5 |
cmd6 |
(...) |
cmdN > result.txt

(দ্রষ্টব্য যে পাইপ দিয়ে লাইন শেষ হলে কোনও পিছনে পিছনে থাকা দরকার নেই sh)

জোনাসের পর্যবেক্ষণ অনুযায়ী আপডেট করুন
যদি সিএমডি 3 শূন্য-বহির্গমন কোড দিয়ে শেষ করতে পারে এবং আপনি catবাকী ইনপুটটি প্রক্রিয়া করতে না চান তবে যুক্তিটি বিপরীত করুন:

cmd1 < input.txt |
cmd2 |
( [[ ! "${DEFINED}" ]] && cat || cmd3 ) |
cmd4 |
cmd5 |
cmd6 |
(...) |
cmdN > result.txt

সহজ টিপ
বিপরীতমুখী


2
যুক্তিটিকে বিপরীত করা কোনও উপকারে আসে না। যদি catশূন্য-বহির্গমন স্থিতি (সাইনপাইপ পাওয়ার সময় সাধারণ) দিয়ে ফেরত আসে তবে cmd3চালানো হবে। থোরের উত্তর বা চালানো এড়ানো এমন অন্যান্য সমাধান হিসাবে / তারপরে / অন্যথায় ভাল ব্যবহার করুন cat
স্টাফেন চেজেলাস

সুতরাং বিড়াল জিনিসগুলিকে সংযুক্ত করতে ব্যবহার করা যেতে পারে, যেমন "স্ট্রিম" মাধ্যমে প্রবাহিত হয়
আলেকজান্ডার মিলস

19

if/ else/ fiকাজ করে। বোর্নের মতো কোনও শেল ধরে নেওয়া:

cmd1 < input.txt |
cmd2 |
if [ -n "$DEFINED" ]; then cmd3; else cat; fi |
cmd4 |
cmd5 |
cmd6 |
(...) |
cmdN > result.txt

10

এখনও পর্যন্ত দেওয়া সমস্ত উত্তরগুলি প্রতিস্থাপন cmd3করে cat। আপনি এর সাথে কোনও কমান্ড চালানো এড়াতে পারেন:

if [ -n "$DEFINE" ]; then
  alias maybe_cmd3='cmd3 |'
else
  alias maybe_cmd3=''
fi
cmd1 |
cmd2 |
maybe_cmd3
cmd4 |
... |
cmdN > result.txt

এটি পজিক্স, তবে নোট করুন যে কোনও bashস্ক্রিপ্টে যেখানে bashইন- shমোড নেই (যেমন কোনও স্ক্রিপ্ট দিয়ে শুরু হচ্ছে #! /path/to/bash), আপনাকে shopt -s expand_aliases(বা set -o posix) দিয়ে উপন্যাস প্রসারণ সক্ষম করতে হবে ।

আরেকটি পদ্ধতি যা এখনও কোনও অপ্রয়োজনীয় কমান্ড চালায় না তা হল ইওল ব্যবহার:

if [ -n "$DEFINE" ]; then
  maybe_cmd3='cmd3 |'
else
  maybe_cmd3=''
fi
eval "
  cmd1 |
  cmd2 |
  $maybe_cmd3
  cmd4 |
  ... |
  cmdN > result.txt"

বা:

eval "
  cmd1 |
  cmd2 |
  ${DEFINE:+cmd3 |}
  cmd4 |
  ... |
  cmdN > result.txt"

লিনাক্সে (কমপক্ষে) পরিবর্তে cat, আপনি দুটি পাইপের মধ্যে ডেটা পাস করার জন্য + এর পরিবর্তে pv -qকোনটি ব্যবহার করেন যা কার্নেল এবং ব্যবহারকারীর স্পেসের মধ্যে ডেটা দু'বার সরিয়ে নেওয়া এড়ানো যায়।splice()read()write()


9

মানাটওয়ার্কের গৃহীত উত্তরের সংযোজন হিসাবে : এবং-মিথ্যা-বা গোটচা এবং স্ট্রিমগুলির সাথে এর মিথস্ক্রিয়া সম্পর্কে সচেতন হন। এই ক্ষেত্রে,

true && false || echo foo

আউটপুট foo। এটি আশ্চর্যজনক নয় যে,

true && (echo foo | grep bar) || echo baz

এবং

echo foo | (true && grep bar || echo baz)

উভয় আউটপুট baz। (নোট যেটি echo foo | grep barমিথ্যা এবং এর কোনও আউটপুট নেই)। যাহোক,

echo foo | (true && grep bar || sed -e abaz)

কিছুই আউটপুট। এটি আপনি যা চান তা হতে পারে বা নাও পারে।


এখানে এটি কীভাবে প্রাসঙ্গিক তা আমি দেখতে পাচ্ছি না। else(অথবা ||) একটি নাল অপারেশন ইনপুট অপরিবর্তিত রেখে হিসাবে কাজ করা উচিত নয়। সুতরাং আপনার কোডকে অপ্রাসঙ্গিক করে তোলে এমন সমস্ত কিছু পরিবর্তন করে প্রতিস্থাপন catকরা echo। "এবং-মিথ্যা-বা গোটচা" সম্পর্কিত, আমি পাইপলাইনের সাথে কোনও হস্তক্ষেপ দেখতে পাচ্ছি না: পেস্টবিন.ইউ
ইউ

5
@manatwork: একটা জিনিষ জোনাস ইশারা করা হয় যে, এ [[ "${DEFINED}" ]] && cmd3 || cat, cmd3এবং catপারস্পরিক একচেটিয়া নয় thenএবং elseএকই শাখা if, কিন্তু যে যদি cmd3ব্যর্থ হয়, তারপর catএছাড়াও মৃত্যুদন্ড কার্যকর করা হবে না। (অবশ্যই, যদি cmd3সর্বদা সফল হয়, বা যদি এটি সমস্ত ইনপুট গ্রহণ করে তবে প্রক্রিয়া করার stdinজন্য কিছুই অবশিষ্ট নেই cat, তবে এটি কোনও ব্যাপার না)) আপনার যদি উভয় thenএবং elseশাখাগুলির প্রয়োজন হয় তবে এটি একটি স্পষ্টত ifকমান্ড ব্যবহার করা ভাল , &&এবং না ||
ম্যাসিফিল 21

1
@ মুশিফিল, ব্যাখ্যাটির জন্য আপনাকে ধন্যবাদ। এখন আমি জোনাসের যুক্তি বুঝতে পেরেছি।
manatwork

4

আমার একই রকম পরিস্থিতি ছিল যা আমি ব্যাশ ফাংশন দিয়ে সমাধান করেছি :

if ...; then
  my_cmd3() { cmd3; }
else
  my_cmd3() { cat; }
if

cmd1 < input.txt |
cmd2 |
my_cmd3 |
cmd4 |
cmd5 |
cmd6 |
(...) |
cmdN > result.txt

3

এখানে বিকল্প সম্ভাব্য সমাধানটি রয়েছে:
সিউডো-পাইপলাইন তৈরি করতে নামযুক্ত পাইপগুলি সংশ্লেষ করা:

dir="$(mktemp -d)"
fifo_n='0'
function addfifo {
 stdin="$dir/$fifo_n"
((fifo_n++))
[ "$1" ] || mkfifo "$dir/$fifo_n"
stdout="$dir/$fifo_n"; }

addfifo; echo "The slow pink fox crawl under the brilliant dog" >"$stdout" &

# Restoring the famous line: "The quick brown fox jumps over the lazy dog"
# just replace 'true' with 'false' in any of the 5 following lines and the pseudo-pipeline will still work
true && { addfifo; sed 's/brilliant/lazy/' <"$stdin" >"$stdout" & }
true && { addfifo; sed 's/under/over/'     <"$stdin" >"$stdout" & }
true && { addfifo; sed 's/crawl/jumps/'    <"$stdin" >"$stdout" & }
true && { addfifo; sed 's/pink/brown/'     <"$stdin" >"$stdout" & }
true && { addfifo; sed 's/slow/quick/'     <"$stdin" >"$stdout" & }

addfifo -last; cat <"$stdin"

wait; rm -r "$dir"; exit 0

2

ভবিষ্যতের রেফারেন্সের জন্য, আপনি যদি মাছের শর্তসাপেক্ষ পাইপগুলি সন্ধান করতে এখানে আসেন , আপনি এটি এটি করেন:

set -l flags "yes"
# ... 
echo "conditionalpipeline" | \
  if contains -- "yes" $flags 
    sed "s/lp/l p/"
  else
    cat
  end | tr '[:lower:]' '[:upper:]'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.