কেন '>' জিসিসি থেকে ত্রুটি বার্তাগুলি পুনর্নির্দেশ করে না?


9

আমি নিম্নলিখিত প্রোগ্রামটি new.c এ সংরক্ষণ করেছি

int main() 
{ 
    a;
    return 0; 
}

এটি একটি ত্রুটি বার্তা দেয়। আমি এই বার্তাটি একটি ফাইলে প্রেরণ করতে চাই। সুতরাং আমি নিম্নলিখিত কমান্ডটি ব্যবহার করেছি

gcc new.c > temp.txt

তবে তবুও আমি টার্মিনালে আউটপুট পাচ্ছিলাম। আমি উবুন্টু 13.04 ব্যবহার করছি। আমি কীভাবে এটি কাজ করতে পারি?


উত্তর:


16

আপনি যখন একটি প্রোগ্রাম সংকলন করেন gcc, সেখানে বিভিন্ন ধরণের আউটপুট থাকে: থেকে stdoutএবং stderr। সাধারণত, ফাইলটি একটি ফাইলের দিকে >সরাসরি stdoutপ্রবাহিত করে (উদাহরণস্বরূপ, এর ফলাফল printf("hello world\n");প্রেরণ করা হয় stdout)। তবে, stderrস্ক্রিনে প্রেরণ করা অবিরত থাকবে, যেহেতু এটি "ব্যতিক্রমী কিছু যা আপনার সম্পর্কে বলা দরকার" বলে ধরে নেওয়া হয়।

স্টাডারকে একটি ফাইলে পুনঃনির্দেশ করার একটি উপায় রয়েছে - আপনি নিম্নলিখিত (খুব স্বজ্ঞাত নয়) কমান্ড দিয়ে এটি করুন:

gcc new.c &> myFile

&>"সবকিছু পুনর্নির্দেশ" এর জন্য "বাশ শর্টহ্যান্ড" কোথায় ? @ চার্লসডুফি দ্বারা নির্দেশিত হিসাবে, পসিক্স অনুগত ফর্মটি

gcc new.c > myFile 2>&1

এই মানে হলো "কম্পাইল 'new.c' এবং সেন্ড stdoutকরতে myFile। এবং পাঠান stderrহিসাবে একই জায়গা (2) stdout( &1stdout- এ হিসাবে একই জায়গা" =) "।

আপনি বিভিন্ন পুনঃনির্দেশ আরও বিশদের পাবেন http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html এবং http://mywiki.wooledge.org/BashFAQ/055

যাইহোক, আপনি যদি আপনার প্রোগ্রামের মধ্যে থেকে কিছু নির্দিষ্টভাবে প্রেরণ করতে চান তবে নীচের মাধ্যমে আপনি এটি stderrকরতে পারেন

fprintf(stderr, "hello world - this is urgent.\n");

যদি আপনি এটি কোনও প্রোগ্রামে অন্তর্ভুক্ত করেন তবে প্রোগ্রামটি চালান এবং একটি "সাধারণ" আউটপুট কোনও ফাইলে প্রেরণ করুন, এটি এখনও কনসোলে উপস্থিত হবে। সুতরাং আপনি যদি এক্সিকিউটেবলের উপরেরটি সংকলন করেন urgentতবে টাইপ করুন

./urgent > /dev/null

কনসোলে আপনার আউটপুট স্ক্রিনে উপস্থিত হবে।


2
mywiki.wooledge.org/BashFAQ/055 সম্ভবত পুনঃনির্দেশের আরও ভাল পরিচিতি। এছাড়াও, একজনের পশিক্স-কমপ্লায়েন্ট ফর্ম ( >myFile 2>&1) পাশাপাশি বাশ এক্সটেনশন ( &>) প্রবর্তন করা উচিত ।
চার্লস ডাফি

@ চার্লসডুফি - উভয়ই খুব ভাল পয়েন্ট। আমি তাদের সম্পূর্ণতার জন্য আমার উত্তরে অন্তর্ভুক্ত করব।
ফ্লোরিস

11

যেহেতু >শুধুমাত্র স্টডআউট পুনর্নির্দেশ করে, এবং ত্রুটিগুলি এতে লিখিত হয় stderr, আপনার পরিবর্তে নিম্নলিখিতগুলির একটি ব্যবহার করতে হবে:

gcc new.c &> temp.txt ## redirect both stdout and stderr using bash or zsh only

... অথবা ...

gcc new.c >temp.txt 2>&1 ## redirect both stdout and stderr in any POSIX shell

&>BASH এক্সটেনশন যা উভয় stdoutএবং stderrএকটি ফাইলের পুনঃনির্দেশ ; অন্যথায়, সবচেয়ে সহজ পদ্ধিতি হল পদ্ধতির প্রথম পুনর্নির্দেশ stdout- এ (হয় >temp.txt), এবং তারপর দ্বারা stderr করা (এফডি 2) stdout- এ ইতিমধ্যেই-পুনঃনির্দেশিত ফাইল হ্যান্ডেল একটি অনুলিপি (এফডি 1), যেমন: 2>&1


4

অন্যরা যেমন বলেছে, লিনাক্স দুটি পৃথক আউটপুট স্ট্রিম সরবরাহ করে:

স্টাডাউট বা "স্ট্যান্ডার্ড আউটপুট" হ'ল যেখানে সমস্ত নিয়মিত আউটপুট যায়।
              আপনি ফাইল বর্ণনাকারী ব্যবহার করে এটি রেফারেন্স করতে পারেন 1

দ্বারা stderr , বা "মান ত্রুটি" আউট-অফ-ব্যান্ড তথ্যের জন্য একটি পৃথক প্রবাহ হয়।
              আপনি ফাইল বর্ণনাকারী ব্যবহার করে এটি রেফারেন্স করতে পারেন 2

দুটি ভিন্ন আউটপুট স্ট্রিম কেন? কাল্পনিক আদেশগুলির একটি পাইপলাইন বিবেচনা করুন:

 decrypt $MY_FILE | grep "secret" | sort > secrets.txt

এখন ভাবুন decryptকমান্ডটি ব্যর্থ হয়েছে এবং একটি ত্রুটি বার্তা উত্পন্ন করে। যদি এটি সেই বার্তাটি stdoutপ্রেরণ করে তবে এটি পাইপটিতে প্রেরণ করবে এবং এটি "গোপন" শব্দটি না থাকলে আপনি কখনই দেখতে পাবেন না। সুতরাং আপনি কী খালি হয়েছে তার কোনও ধারণা ছাড়াই একটি খালি আউটপুট ফাইলটি শেষ করবেন।

তবে, পাইপ কেবল ক্যাপচার stdoutকরায়, decryptকমান্ডটি তার ত্রুটিগুলি এখানে প্রেরণ করতে পারে stderr, যেখানে সেগুলি কনসোলে প্রদর্শিত হবে be

আপনি পুনর্নির্দেশ করতে পারেন stdoutএবং stderr, হয় একসাথে একত্র হওয়া বা স্বাধীনভাবে:

# Send errors to "errors.txt" and output to "secrets.txt"
# The following two lines are equivalent, as ">" means "1>"
decrypt $MY_FILE 2> errors.txt > secrets.txt
decrypt $MY_FILE 2> errors.txt 1> secrets.txt

আপনি ত্রুটিগুলি পুনর্নির্দেশ করতে পারেন stdoutএবং এগুলি প্রক্রিয়া করতে পারেন যেন তারা স্বাভাবিক আউটপুট থাকে:

# The operation "2>&1" means "redirect file descriptor 2 to file
# descriptor 1. So this sends all output from stderr to stdout.
# Note that the order of redirection is important.
decrypt $MY_FILE > errors.txt 2>&1 

# This may be confusing.  It will store the normal output in a file
# and send error messages to stdout, where they'll be captured by 
# the pipe and then sorted.
decrypt $MY_FILE 2>&1 > output.txt | sort

আপনি stdout এবং stderr উভয় একই ফাইলে পুনর্নির্দেশ করতে একটি "শর্টহ্যান্ড" স্বরলিপি ব্যবহার করতে পারেন :

decrypt $MY_FILE &> output.txt

এবং, অবশেষে, >অপারেটর প্রথমে লেখার আগে এর আউটপুট ফাইলটি কেটে ফেলবে । পরিবর্তে, আপনি যদি কোনও বিদ্যমান ফাইলে ডেটা যুক্ত করতে চান তবে >>অপারেটরটি ব্যবহার করুন :

decrypt $MY_FILE 2>> more_errors.txt >> more_secrets.txt
decrypt $MY_FILE >> more_output.txt 2>&1

1
দুটি কুইবল: (১) অব্যর্থিত প্যারামিটার বিস্তৃতি () ব্যবহার করা $FOOবাগের একটি সাধারণ উত্স, এবং উদাহরণগুলিতে এটি প্রদর্শন করা এত দুর্দান্ত নয়। (২) অল আপারকেস ভেরিয়েবল নামের ব্যবহার পরিবেশ এবং অন্তর্নির্মিত ভেরিয়েবল (কনভেনশন দ্বারা বড় হাতের) এবং স্থানীয় ভেরিয়েবল (কনভেনশন দ্বারা ছোট হাতের) মধ্যে নেমস্পেস বিরোধের প্রাথমিক কারণ। (৩) >>একবারে কোনও ফাইল খোলার পরিবর্তে এবং একাধিক কমান্ড দ্বারা ফাইল বিবরণকারীকে ফাইলের জন্য খোলা রেখে অকার্যকর কোডের ফলস্বরূপ লোককে বারবার ব্যবহার করার জন্য উত্সাহিত করা (যা ফাইলটি পুনরায় খোলে যা কোনও কমান্ডে ব্যবহার করা হয়) des
চার্লস ডাফি

... শেষ পয়েন্টে, এর সাথে তুলনা করুন: exec 4>secrets; echo "this is a secret" >&4; echo "this is another secret" >&4
চার্লস ডাফি

+1 আমাকে সৎ রাখার জন্য ধন্যবাদ, @ চারেলস ডফি। সমস্ত ভাল পয়েন্ট। আমি ইচ্ছাকৃতভাবে execসরলতার জন্য বাদ দিয়েছি , যদিও বাস্তবে এটি সাধারণত আরও ভাল কৌশল।

এছাড়াও, ধসে যেতে পারে বা (যেখানে স্পেস আগে ও পরে হতে হবে A, এবং সামনে )। command₁ > output_file ; command₂ >> the_same_output_file( command₁ ; command₂ )  > output_file{ command₁ ; command₂ ;  }  > output_file{;}
জি-ম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.