পাইপ ব্যবহার করে বাশ ফাংশন কীভাবে রচনা করবেন?


18

আমার এই ফ্যাশনে সংজ্ঞায়িত কয়েকটি ফাংশন রয়েছে:

function f {
  read and process $1
  ...
  echo $result
}

আমি তাদের একসাথে রচনা করতে চাই যাতে অনুরোধটি দেখতে ভাল লাগে f | g | h

স্ট্যান্ডিনের এক পড়ার আর্গুমেন্টে আর্গুমেন্টের সাথে কাজ করে ফাংশনটি রূপান্তর করতে আমি কী মূর্খ শব্দটি ব্যবহার করি? এড়াতে বাছাই ছাড়াই স্ট্রিম থেকে জোড়, যুক্তিগুলির দ্বিগুণগুলি পড়া কি সম্ভব (উদাহরণস্বরূপ নাল টার্মিনেশন)?


হয় আপনি কিছু চান h(g(f(...)))বা ফাংশনগুলির প্রতিটি স্ট্যান্ডার্ড ইনপুট ( read x; ...) থেকে পড়ে এবং স্ট্যান্ডার্ড আউটপুট ( echo ...) এ লেখেন ।
ভনব্র্যান্ড

উত্তর:


21

একটি সম্ভাব্য পন্থা while...readহ'ল আপনার ফাংশনগুলির মধ্যে এমন একটি কন্সট্রাক্ট স্থাপন করা যা এসটিডিআইএন এর মাধ্যমে ফাংশনে আসা যে কোনও ডেটা প্রক্রিয়া করবে, এটি পরিচালনা করবে এবং তারপরে ফলাফলটি ডেটা এসটিডিউটের মাধ্যমে নির্গত করবে।

function X {
  while read data; do
    ...process...
  done
}

আপনার while ..read..উপাদানগুলি কীভাবে কনফিগার করবেন সেগুলি যত্ন সহকারে ব্যয় করতে হবে যেহেতু তারা নির্ভরযোগ্যভাবে গ্রাহ্য করতে সক্ষম হবেন এমন ডেটার ধরণের উপর নির্ভরশীল। একটি অনুকূল কনফিগারেশন থাকতে পারে যা আপনি সামনে আসতে পারেন।

উদাহরণ

$ logF() { while read data; do echo "[F:$(date +"%D %T")] $data"; done; }
$ logG() { while read data; do echo "G:$data";                    done; }
$ logH() { while read data; do echo "H:$data";                    done; }

এখানে প্রতিটি ফাংশন নিজেই's

$ echo "hi" | logF
[F:02/07/14 20:01:11] hi

$ echo "hi" | logG
G:hi

$ echo "hi" | logH
H:hi

যখন আমরা তাদের একসাথে ব্যবহার করি তারা এখানে।

$ echo "hi" | logF | logG | logH
H:G:[F:02/07/14 19:58:18] hi

$ echo -e "hi\nbye" | logF | logG | logH
H:G:[F:02/07/14 19:58:22] hi
H:G:[F:02/07/14 19:58:22] bye

তারা ইনপুট বিভিন্ন স্টাইল নিতে পারেন।

#-- ex. #1
$ cat <<<"some string of nonsense" | logF | logG | logH
H:G:[F:02/07/14 20:03:47] some string of nonsense

#-- ex. #2    
$ (logF | logG | logH) <<<"Here comes another string."
H:G:[F:02/07/14 20:04:46] Here comes another string.

#-- ex. #3
$ (logF | logG | logH)
Look I can even
H:G:[F:02/07/14 20:05:19] Look I can even
type to it
H:G:[F:02/07/14 20:05:23] type to it
live
H:G:[F:02/07/14 20:05:25] live
via STDIN
H:G:[F:02/07/14 20:05:29] via STDIN
..type Ctrl + D to stop..

#-- ex. #4
$ seq 5 | logF | logG | logH
H:G:[F:02/07/14 20:07:40] 1
H:G:[F:02/07/14 20:07:40] 2
H:G:[F:02/07/14 20:07:40] 3
H:G:[F:02/07/14 20:07:40] 4
H:G:[F:02/07/14 20:07:40] 5

#-- ex. #5
$ (logF | logG | logH) < <(seq 2)
H:G:[F:02/07/14 20:15:17] 1
H:G:[F:02/07/14 20:15:17] 2

4

স্ল্যামের উত্তরের সংযোজন হিসাবে আমি ফাংশন আর্গুমেন্ট হিসাবে নাল-বিচ্ছিন্ন টিপলসের সাথে কিছু পরীক্ষা-নিরীক্ষা করেছি:

$ sayTuple() { 
    IFS= read -r -d $'\0' d1
    IFS= read -r -d $'\0' d2
    echo "sayTuple: -$d1- -$d2-"
}

দ্রষ্টব্য: sayTupleদু'বার নাল-টার্মিনেটেড রেকর্ড পড়ে যে -d $'\0'কোনও স্থানের আশেপাশের ইনপুট পরিচালনা করে IFS=echoচারপাশে ঘিরে রেকর্ড-

ফলাফল এটি সঠিকভাবে নাল-টার্মিনেটড ইনপুট যুক্ত হ্যান্ডেলগুলি দেখায় \nএবং \t:

$ printf "%s\0%s\0" "Hello " $' Brave\n\tWorld' | sayTuple 
sayTuple: -Hello - - Brave
        World-

মন্তব্যে উন্নতির জন্য দয়া করে পরামর্শ যুক্ত করুন, এটি একটি আকর্ষণীয় বিষয়।


আপনার ধারণার মত +1। এর পরিবর্তে আমরা ভিতরে একটি লুপ রাখতে পারি যা এটি # এর আর্ট্রিট্রি আর্গুমেন্ট নিতে দেয়। sayTuple() { arr=() ; while IFS= read -r -d $'\0' arg; do arr+="$arg"; done; echo "sayTuple: ${arr[@]}"; }
SLM

দেখে মনে হচ্ছে আপনার করা উচিত IFS= read -r -d $'\0' -a argতবে আমি এটি কাজ করতে পারি না। এটি অপসারণের অনুমতি দেয় while, যা অপ্রয়োজনীয় বলে মনে হয়, তবে আমি কাজ করতে পারি এমন একমাত্র প্যাটার্ন।
slm
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.