কমান্ড সফল হলে আমি কীভাবে আউটপুট দমন করতে পারি?


22

আমি সাধারণত সফল যে সেকেন্ডারি কমান্ডগুলির আউটপুট দমন করে একটি স্ক্রিপ্টের আউটপুট সহজ করতে চাই।

যাইহোক, -qএগুলি ব্যবহার করে আউটপুটটি লুকিয়ে রাখে যখন তারা মাঝে মধ্যে ব্যর্থ হয় তাই আমার ত্রুটি বোঝার উপায় নেই। অতিরিক্তভাবে, এই কমান্ডগুলি তাদের আউটপুট লগ করে stderr

কমান্ডের আউটপুট কেবল তখনই সাফল্যের সাথে দমন করার কোনও উপায় আছে ?

উদাহরণস্বরূপ (তবে সীমাবদ্ধ নয়) এর মতো কিছু:

mycommand | fingerscrossed

যদি সবকিছু ঠিকঠাক হয় fingerscrossedতবে আউটপুটটি ক্যাচ করে তা বাতিল করে দেয়। অন্যথায় এটি স্ট্যান্ডার্ড বা ত্রুটি আউটপুট (যাই হোক না কেন) এর প্রতিধ্বনি দেয়।

উত্তর:


36

moreutils' chronicকমান্ড আছে শুধু যে:

chronic mycommand

mycommandযদি এটি ব্যর্থ না হয় তবে আউটপুট গিলে ফেলবে , যেখানে আউটপুট প্রদর্শিত হবে।


1
ধন্যবাদ. আমি এটি গ্রহণ করেছি এটি বেশিরভাগ ইউনিক্স ওএসে ডিফল্টরূপে ইনস্টল করা হয়নি?
ম্যাথিউ নাপোলি

1
সম্ভবত না, যদিও এটি ব্যাপকভাবে প্যাকেজড তাই এটি ইনস্টল করা সহজ হওয়া উচিত।
স্টিফেন কিট

1
এটি প্যাকেজে ডেবিয়ান রয়েছে moreutils। আমার পক্ষে ভাল
লাগল

6
মনে রাখবেন এটি মেমরির পুরো আউটপুট সংরক্ষণ করে।
স্টাফেন চেজেলাস

1
@ স্টাফেনচেজেলাস সম্ভবত এটির মতো কোনও কিছু বাস্তবায়নের একমাত্র উপায়, কমান্ডের প্রয়োজন হলে চালানো অবস্থায় আউটপুট সংরক্ষণ করা দরকার stored
সেন্টিমানে

11
### do this bit once at the top of your script
divert=
exec 3<>"${divert:=$(mktmp)}" 4<>/dev/null
rm -- "$divert"; unset divert
### then do this bit as often as needed
command >&3 2>&3
cat <&3 >&"$(((RTN=$?)?2:4))"

সম্ভবত কৌশলটি করা উচিত। এটি প্রতিটিের আউটপুটটিকে commandমুছে ফেলা অস্থায়ী ফাইলে বাফার করবে এবং এরপরে /dev/nullতার অবস্থানটি শূন্য ছিল না বা না তার উপর নির্ভর করে তার আউটপুটটি সিডন বা স্টেডারে স্থান করে দেবে। কারণ টেম্প ফাইলটি আগেই মুছে ফেলা হয় এটি কোনও প্রক্রিয়া দ্বারা পড়া যায় না তবে বর্তমান শেল এবং তার শিশুদের ফাইল বিবরণীতে ( /proc/$pid/fdযথাযথ অনুমতি সহ স্নুপগুলি বাদ দেওয়া) , এবং এটির মাধ্যমে আপনি পরিষ্কার করার প্রয়োজন হয় না।

লিনাক্স সিস্টেমে সম্ভবত আরও সুবিধাজনক সমাধান:

divert(){
    "$@" >&3 2>&3 ||
    eval "cat <&3
          return $?"
}   3<<"" 3<>/dev/fd/3

... যা, সবচেয়ে শাঁস, অন্যান্য মতো কাজ করে, ছাড়া তুমি এটা পছন্দ কল করতে পারেন: divert some simple-command with args। উচ্চ আউটপুট কমান্ড থেকে সাবধান "$@", যদিও জন্য dash, yashবা অন্য শাঁস যা পাইপ এখানে-নথি না - আমি এটা নল বাফার ভরাট ঐ শাঁস মধ্যে সম্ভব হতে পারে মনে (linuxes উপর প্রায় 128kb একটি ডিফল্ট কোণে) এবং তাই অচলাবস্থা । যে জন্য একটি চিন্তা করা উচিত হবে না ksh, mksh, bash, zsh, অথবা বোর্ন শেল, যদিও - আমি স্পষ্টভাবে সাথে উপরে করেনি ঐ সব মূলত একই জিনিস করে exec


9

সাধারণত ত্রুটির ক্ষেত্রে কমান্ড stderrআপনার কাজের জন্য বার্তা আউটপুট করে দেয় আপনি কেবল দমন করতে পারেনstdout

mycommand > /dev/null


আপনাকে ধন্যবাদ, তবে আমি যেমন প্রশ্নে বলেছি আমার কমান্ডগুলি সমস্ত আউটপুট লগ ইন করে stderr(তাই এটির কোনও প্রভাব নেই)।
ম্যাথিউ নাপোলি

4

নিজের ক্রনিক তৈরি করতে To

my_chronic() {
  tmp=$(mktemp) || return # this will be the temp file w/ the output
  "$@"  > "$tmp" 2>&1 # this should run the command, respecting all arguments
  ret=$?
  [ "$ret" -eq 0 ] || cat "$tmp"  # if $? (the return of the last run command) is not zero, cat the temp file
  rm -f "$tmp"
  return "$ret" # return the exit status of the command
}

3

আমি আমার মেকফিলগুলিতে এরকম কিছু করি:

if (mycommand) &> mycommand.log; then 
  echo success 
else 
  c=$?; 
  echo;echo -e "Bad result from previous command, see mycommand.log for more details";echo;
  command_to_run_on_fail
  (exit $c)
fi

আপনার অবস্থার সাথে এটি মানিয়ে নেওয়া, আপনি এর মতো কিছু করতে পারেন:

if ! (mycommand) &> mycommand.log; then 
  c=$?; 
  cat mycommand.log
  rm mycommand.log
  (exit $c)
fi

সুতরাং, "if" কমান্ডটি চালায় এবং আউটপুটটি মাইকম্যান্ড.লগে পাইপ দেয়। আপনার যদি স্টাডাউট বনাম স্টডআউট বনাম যা কিছু ধরতে হয় তবে পাইপ কমান্ড '&>' থেকে '>' পরিবর্তন করতে হতে পারে। যদি কমান্ডটি ব্যর্থ হয় তবে ত্রুটি কোডটি ক্যাপচার করুন, মাইকম্যান্ড.লগের সামগ্রীগুলি মুদ্রণ করুন, মাইকম্যান্ড.লগ সরান এবং শেষ পর্যন্ত মূল ত্রুটি কোড সহ ফিরে আসুন।

(প্রস্থান $ সি) ব্যতীত আপনি প্রস্থান কোডটি দিয়ে ফিরে আসতে পারেন যা 'আরএম' কমান্ডটি ফিরে আসার সাথে মেলে।

অবশেষে, আপনি যদি একটি লাইনার চান তবে এর মতো কিছু কাজ করবে।

mycommand &> mycommand.log || cat mycommand.log; rm mycommand.log

2
আপনি কি সত্যিই আপনার আদেশগুলি / ইত্যাদি মোড়ান। মধ্যে (...)যে মত? কারণ এটি আপনার পক্ষে কার্যকর কোনও কাজ করে না তবে অতিরিক্ত সাব-শেলগুলি পোড়ায়।
এটান রিজনার

@ ইটানরাইজনার (exit $c)সেট করছে $?, যা এমন কিছু যা আপনি অন্যথায় করতে পারেন না। if ! (mycommand) &>xপুনর্নির্দেশের সাথে অর্থবহ হয় যদি কমান্ডটি উদাহরণ ব্যবহার করে timeবা শেল ত্রুটি দেয়।
মাইকেল হোমার

@ { ; }মিশেলহোমর - এই জিনিসগুলির জন্য এখানে কোঁকড়াগুলি রয়েছে ... যদিও স্বল্পত্বে exitসেখানে কিছুটা জটিল।
মাইকসার্ভ

কোনও মেকফিল স্নিপেটে আপনি যদি পূর্বের সংরক্ষিতগুলির সাথে প্রস্থান করার চেষ্টা করছেন $?তবে আপনি কেবল ব্যবহার করতে পারেন exit $cতবে হ্যাঁ, অন্যান্য ক্ষেত্রে (exit $?)এর মান রয়েছে (যদিও শেল ফাংশনটি rret() { return $1; }সাধারণভাবে আমি তর্ক করব)। কমান্ডের সাবশেলটি এখনও মাইক্রোভারের হিসাবে যেমন নির্দেশিত হয়েছে ততটা সত্যই নেই।
এটান রেইজনার

3

আমি এই অন্যান্য প্রশ্নের এই এত সহজ উত্তর পেয়েছি :

output=`mycommand 2>&1` || echo $output

একটি যাদুমন্ত্র মত কাজ করে!


দ্রষ্টব্য: আমার ব্যবহারের ক্ষেত্রে এটি ছিল একটি সহজ সমাধান (সমস্ত সিআই সার্ভারে অতিরিক্ত স্টাফ ইনস্টল করা এড়াতে) তাই আমি এটিকে গ্রহণযোগ্য হিসাবে চিহ্নিত করতে বেছে নিয়েছি। YMMV।
ম্যাথিউ নাপোলি

মনে রাখবেন যে আপনি যদি নিজের শেল স্ক্রিপ্টে সেট-ও xtrace ব্যবহার করেন তবে অ্যাসাইনমেন্ট আউটপুট = ... :-) এর বিশদ লগ করার অংশ হিসাবে সমস্ত আউটপুট আবার উপস্থিত হবে। সেক্ষেত্রে দীর্ঘস্থায়ী ব্যবহার করা সম্ভবত ভাল।
জানু-ফিলিপ গেহর্ক্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.