কীভাবে PIPESTATUS এবং ব্যাশ স্ক্রিপ্টে আউটপুট পাওয়া যায়


9

আমি এই কমান্ডটি দিয়ে একটি ফাইলের সর্বশেষ পরিবর্তনের তারিখ পাওয়ার চেষ্টা করছি

TM_LOCAL=`ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'`

এই লাইনটি কার্যকর করার পরে TM_LOCAL এর "2012-05-16 23:18" এর মতো মান রয়েছে

আমি ত্রুটি আছে কিনা তা দেখতে পাইপস্ট্যাটাস পরীক্ষা করতে চাই। উদাহরণস্বরূপ, যদি ফাইল উপস্থিত না থাকে, ls2 প্রদান করে But তবে $?এর মান 0 রয়েছে কারণ এটির ফেরতের মান রয়েছে awk

আমি যদি এই কমান্ডটি একা চালাই তবে আমি ls এর রিটার্ন মানটি দেখে যাচাই করতে পারি ${PIPESTATUS[0]}

ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'

তবে $PIPESTATUSআমি যেমনটি প্রত্যাশা করেছিলাম তেমন কাজ করে না যদি আমি প্রথম উদাহরণের মতো আউটপুটটি একটি ভেরিয়েবলের কাছে নির্ধারণ করি। এই ক্ষেত্রে $PIPESTATUSঅ্যারেতে কেবল 1 টি উপাদান রয়েছে যা একই$?

সুতরাং, প্রশ্নটি হল, আমি কীভাবে দুজনেই পেতে পারি $PIPESTATUSএবং একই সাথে আউটপুটকে একটি ভেরিয়েবলের বরাদ্দ করতে পারি ?

উত্তর:


8

আপনি এটি করতে পারেন:

TM_LOCAL=$(ls -l --time-style=long-iso ~/.vimrc | \
             awk '{ print $6" "$7 }' ; exit ${PIPESTATUS[0]} )

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

পূর্ণ PIPESTATUSঅ্যারে এবং আউটপুট পাওয়ার এখানে একটি ব্যয়বহুল উপায় । খুব মার্জিত নয়, তবে অন্য কিছু খুঁজে পান নি:

result=$(echo -e "a\nb\nc" | \
          ( cat ; exit 1 ) | \
          ( cat ; exit 42 ) ; echo ${PIPESTATUS[@]})
output=$(head -n -1 <<< "$result")
status=($(tail -n 1 <<< "$result"))
echo "Output:"
echo "$output"
echo "Results:"
echo "${status[@]}"

যা দেয়:

Output:
a
b
c
Results:
0 1 42

আমার ক্ষেত্রে এটি কাজ, তবে আমি সম্পূর্ণ পাইপস্ট্যাটাস অ্যারে এবং আউটপুট পাওয়ার কোনও উপায় আছে কিনা তা সম্পর্কে এখনও আমি আগ্রহী।
মোস্তফা সর্দার Şanlı

3

ব্যবহারের set -o pipefailমধ্যে bashযেমন পাইপ কমান্ড ক্রম ডান-সবচেয়ে নন-জিরো প্রস্থান কোড পাওয়ার জন্য $?। থেকে man bash:

যদি সেট করা থাকে তবে পাইপলাইনের রিটার্ন মান হ'ল শূন্য-স্থিতি সহ প্রস্থান করার জন্য সর্বশেষ (ডানদিকে) কমান্ডের মান বা পাইপলাইনে সমস্ত কমান্ড সফলভাবে প্রস্থান করলে zero এই অপশনটি পূর্বনির্ধারণ অনুসারে নিষ্ক্রিয়।

তারপরে আপনি কেবল অ্যাক্সেস করতে পারেন $?set +o pipefailআবার অক্ষম করতে ব্যবহার করুন ।


2

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

declare -a status
status=(${PIPESTATUS[@]})

এক্সেস তারপর ${status[0]}, ${status[1]}ইত্যাদি


2

"আপনি যা প্রত্যাশা করেন" এর সাথে মুখ্য সমস্যাটি হ'ল ব্যাককোটে একটি কমান্ড সাবসেলের মধ্যে কার্যকর করা হয়; $PIPESTATUSসেখানে উপস্থিত রয়েছে এবং স্থিতি থেকে এটি ফিরে আসে একই নিয়মগুলি অনুসরণ করে যেমন আপনি একটি একক এক্সিকিউটেবল (বা শেল স্ক্রিপ্ট) কার্যকর করেছেন। ব্যাককোটি কমান্ডের স্থিতি হ'ল সঠিকতম ( awk) স্থিতি।

@ ড্যানিয়েল বেক যা বলেছিলেন তা বাস্তবায়নের জন্য , pipefailসাবস্কেলে এইভাবে বিকল্পটি সেট করুন :

TM_LOCAL=`set -o pipefail; ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'` এখন এর $?পরে সঞ্চিত স্থিতি হবে ls(যদি শূন্য নয়) status

যাইহোক, আমি মনে করি একটি সুস্পষ্ট if [ -f ~/.vimrc ];... পরীক্ষা আরও পঠনযোগ্য হবে।

আপনি কোনও পরিবর্তনশীলতে আউটপুট পেতে পারবেন না এবং PIPESTATUSপ্রাক্তনটির জন্য কোনও অস্থায়ী ফাইল না করে বা পরে একটি স্ট্রিংয়ে মার্শাল করে না দিয়ে ফিরে আসতে পারবেন ।


0

আমি প্রস্থান স্থিতি শূন্য না হলে কেবল ইমেল ফ্রন ক্রোন পাঠাতে চেয়েছিলাম

কৌশলটি হ'ল পাইপলাইনটি শেষ করার জন্য স্টিডিনটি পেতে আপনাকে এটি সাবসেলের মধ্যে রাখা দরকার - তবে এটি পাইপস্ট্যাটাস মানটি গোপন করে ...

পরীক্ষার ক্রোন কিছু আউটপুট আউট এবং 1 বা 0 দিয়ে প্রস্থান করে ...

./testcron | (test ${PIPESTATUS[0]} -ne 0 || mail -s "testcron output" paul)

আপডেট: পাইপলাইন কমান্ড প্রক্রিয়া না করা পর্যন্ত পাইপস্ট্যাটাস দৃশ্যমান নয়


0

একটি বিকল্প একটি কল সঙ্গে তার পরিবর্তনের সময় পেয়ে আগে আপনার ফাইল অস্তিত্বের চেক করা হল stat। যেহেতু statটাইমস্ট্যাম্পের চেয়ে আপনার চেয়ে কিছুটা বেশি রিটার্ন, আপনি প্যারামিটার সম্প্রসারণ ব্যবহার করে এটি ছাঁটাই করতে পারেন।

জিএনইউ stat(যেমন লিনাক্সে) দিয়ে আপনি চালাতে পারেন:

[[ -f ~/.vimrc ]] && TM_LOCAL=$(stat -c '%y' ~/.vimrc 2>/dev/null)
TM_LOCAL=${TM_LOCAL%:*}  # Safe to do, even if stat fails

ম্যাক ওএস এক্স এবং অন্যান্য বিএসডি সিস্টেমে statসিনট্যাক্স আলাদা হয় এবং একটি সময় বিন্যাস নির্দিষ্ট করতে পারে:

[[ -f ~/.vimrc ]] && TM_LOCAL=$(stat -f '%Sm' -t '%Y-%m-%d %H:%M' ~/.vimrc 2>/dev/null)

এখন জিএনইউয়ের উত্তর কী, আপনি বলেছেন যে পরিবর্তনটি $TM_LOCALনিরাপদ। এটি কেবল তখনই নিরাপদ যদি আপনি এটির পূর্বের মান না প্রত্যাশা করেন। বলুন মানটি আগে ছিল 2020-02-27 17:14এবং কোনও ~/.vimrcফাইল নেই। আপনি তারপর ছিল 2020-02-27 17। আমি অতিরিক্ত দুটি &&বা একসাথে শৃঙ্খলা করব (সম্ভবত এটি এতটা সুগঠিত নয়) একটি ifস্তবক ব্যবহার করুন ।
অ্যাডাম কাটজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.