উত্তর:
নিম্নলিখিত ifnotempty
ফাংশনটি আর্গুমেন্ট হিসাবে পাস কমান্ডটিতে তার ইনপুটটি পাইপ করে, ইনপুট খালি থাকলে এটি কিছুই করে না। নল এটি ব্যবহার করার জন্য source --foo
বা sink --bar
লেখা দ্বারা source --foo | pipe_if_not_empty sink --bar
।
pipe_if_not_empty () {
head=$(dd bs=1 count=1 2>/dev/null; echo a)
head=${head%a}
if [ "x$head" != x"" ]; then
{ printf %s "$head"; cat; } | "$@"
fi
}
নকশা নোট:
dd
তার স্ট্যান্ডার্ড ইনপুটটিতে যে বাইটটি পড়তে বলেছে তার চেয়ে বেশি না পড়ার উপর নির্ভর করে ।head -c 1
জন্য উপযুক্ত প্রতিস্থাপন হবে thinkdd bs=1 count=1 2>/dev/null
head -n 1
উপযুক্ত হবে না কারণ head
সাধারণত এটির ইনপুটটি বাফার করে এবং এটি যে রেখাটি আউটপুট করে তার চেয়ে বেশি পড়তে পারে - এবং যেহেতু এটি পাইপ থেকে পড়ছে, অতিরিক্ত বাইটগুলি কেবল হারিয়ে গেছে।read -r head
এবং এমনকি read -r -n 1 head
এখানে উপযুক্ত নয় কারণ প্রথম অক্ষরটি যদি একটি নতুন লাইন head
হয় তবে খালি স্ট্রিংয়ে সেট করা হবে, খালি ইনপুট এবং ফাঁকা লাইন দিয়ে ইনপুটটির মধ্যে পার্থক্য করা অসম্ভব হয়ে পড়ে।head=$(head -c 1)
কারণ যদি প্রথম অক্ষরটি একটি নতুন লাইন হয় তবে কমান্ড প্রতিস্থাপনটি চূড়ান্ত নিউলাইনটি কেটে ফেলবে, খালি ইনপুট এবং ফাঁকা লাইন দিয়ে ইনপুটটির মধ্যে পার্থক্য করা অসম্ভব করে তোলে।cat
দ্বারা </dev/stdin
একটি আণুবীক্ষণিক কর্মক্ষমতা লাভের জন্য।আপনি মেমরি পুরো অন্তর্বর্তী ডেটা সঞ্চয় করার কিছু মনে না করেন, এখানে খুব সামান্য সহজ বাস্তবায়ন pipe_if_not_empty
।
pipe_if_not_empty () {
input=$(cat; echo a);
if [ "x$input" != x"a" ]; then
{ printf %s "${input%a}"; } | "$@"
fi
}
নিম্নলিখিত সতর্কতাগুলির সাথে এখানে একটি সামান্য সরল বাস্তবায়ন:
আবার পুরো ডেটা মেমোরিতে জমা থাকে।
pipe_if_not_empty () {
input=$(cat);
if [ "x$input" != x"" ]; then
{ printf '%s\n' "${input}"; } | "$@"
fi
}
এটি আপনার পক্ষে কাজ করা উচিত
$ --a function-- | [ xargs -r ] --another function--
একটি উদাহরণ
$ echo -e "\n\n" | xargs -r ls
$ # No output. ls did not run.
$ echo -e "\n\n1" | xargs -r ls
ls: cannot access 1: No such file or directory
এটি সহজ তবে এটি আপনার পক্ষে কাজ করা উচিত। যদি আপনার "একটি ফাংশন" খালি স্ট্রিং বা পাইপলাইনের নীচে একটি নতুন লাইন প্রেরণ করে, xargs -r, "অন্য ফাংশন" এর মাধ্যমে উত্তরণকে আটকাবে।
Xargs এর জন্য রেফারেন্স: http://www.oreillynet.com/linux/cmd/cmd.csp?path=x/xargs
-r, --no-run-if-empty
Do not run command if standard input contains only blanks.
নীচের ফাংশনটি 1 ম বাইট পড়ার চেষ্টা করে এবং যদি সাফল্যপূর্ণ ইকো থাকে যা বাকিট এবং বিড়ালগুলি বাকী করে। দক্ষ এবং 100% পোর্টেবল হওয়া উচিত।
if_read() {
IFS="" read -rN 1 BYTE && { echo -nE "$BYTE"; cat; } | "$@";
}
পরীক্ষার কেস:
$ echo -n | if_read wc -c
$ echo | if_read wc -c
1
$ echo -en "\nX" | if_read wc -c
2
$
echo -en "\nX" | pipe_if_not_empty mail -s "Subject line here" foo@bar.com
। এটি এটি মনে করে line
এবং here
উভয়ই ই-মেইলের প্রাপক, বিষয়টিতে টোকেন নয়। বিষয়টি কাজে লাগানোর জন্য আমাকে "
আশেপাশে পালাতে হবে। যাইহোক, pipe_if_not_empty
গৃহীত উত্তর থেকে ফাংশনটি কোনও কিছু ছাড়িয়েও আমার পক্ষে কাজ করে।
কমপক্ষে এর মতো কিছু কাজ করে:
yourcommand | if [ $(wc -c) -gt "0" ]; then yourothercommand; fi
দয়া করে নোট করুন যে উপরেরটি লাইন ফিড এবং অন্যান্য বিশেষ অক্ষরকে আউটপুট হিসাবে বিবেচনা করবে, সুতরাং যদি একটি বিবৃতি আউটপুট হিসাবে বিবেচিত হবে তবে একটি ফাঁকা লাইন চলে গেছে। আপনার আউটপুটটি সাধারণত 1 বাইটের বেশি হওয়া উচিত যদি কেবলমাত্র -gt সীমা বাড়ান :)
yourothercommand
এর আউটপুট কখনও দেখেনা yourcommand
।
পরিবর্তে sender | receiver
:
tester () { local a=$(</dev/stdin); if [[ $a ]]; then printf '%s\n' "$a" | receiver; fi; }
sender | tester
অথবা আপনি গিলের জবাব হিসাবে যেমনটি আর্গুমেন্ট হিসাবে গ্রহণযোগ্য প্রোগ্রামটিকে গ্রহণ করার জন্য এটি পরিবর্তন করে এটি আরও সাধারণ উদ্দেশ্য করতে পারেন:
tester () { local a=$(</dev/stdin); if [[ $a ]]; then printf '%s\n' "$a" | "$@"; fi; }
sender | tester receiver