আপনি সম্ভবত "অনুমতি অস্বীকার" বলতে চাইছেন - find
উবুন্টুতে আপনাকে যা দেখায় যখন আপনি ফাইল অনুমতিের কারণে কোনও কিছুতে অ্যাক্সেস করতে পারবেন না - "অ্যাক্সেস প্রত্যাখ্যান" না হয়ে।
এটি সম্পূর্ণরূপে একটি সাধারণ কমান্ড যা সঠিকভাবে এটি করে (এবং একটি বোনাস হিসাবে অন্যান্য * নিক্স এসের কাছে বহনযোগ্য , ততক্ষণ ত্রুটি বার্তা একই থাকে):
(find 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied') 3>&1 1>&2 2>&3 3>&-
(সাধারণত আপনি কিছু যুক্তি দিতে চান find
Those তারা প্রথম পুনঃনির্দেশের আগে চলে যায় 3>&1
))
তবে, প্রায়শই আপনি সহজ কিছু ব্যবহার করতে সক্ষম হবেন। উদাহরণস্বরূপ, আপনি সম্ভবত প্রক্রিয়া বিকল্প ব্যবহার করতে পারেন । বিশদ অনুসরণ করুন।
সর্বাধিক সাধারণ পদ্ধতি এবং তাদের সীমাবদ্ধতা
দুই টিপিক্যাল পন্থা বর্জন করা হয় দ্বারা stderr (হিসাবে Zanna এর উত্তর ) অথবা করতে দ্বারা stderr পুনর্নির্দেশ করতে stdout- এ (হিসাবে এবং ফিল্টার stdout- এ অ্যান্ড্রয়েড দেবের উত্তর )। যদিও তাদের লেখার সহজ হওয়ার সুবিধা রয়েছে এবং প্রায়শই যুক্তিসঙ্গত পছন্দ হয় তবে এই পদ্ধতিগুলি আদর্শ নয়।
স্টাডারের কাছে প্রেরিত সমস্ত কিছুই ত্যাগ করা - যেমন এটিকে নাল ডিভাইসে পুনর্নির্দেশের মাধ্যমে 2>/dev/null
বা এটির সাথে বন্ধ করে 2>&-
"অনুমতি অস্বীকার" ব্যতীত অন্য কোনও ত্রুটি না থাকার ঝুঁকি রয়েছে।
"অনুমতি প্রত্যাখ্যান করা" সম্ভবত চলমান অবস্থায় দেখা সবচেয়ে সাধারণ ত্রুটি find
, তবে এটি একমাত্র সম্ভাব্য ত্রুটি থেকে দূরে এবং যদি অন্য কোনওটি ঘটে থাকে তবে আপনি এটি সম্পর্কে জানতে চাইতে পারেন। বিশেষত, find
যদি কোনও প্রারম্ভিক অবস্থান উপস্থিত না থাকে তবে "এই জাতীয় কোনও ফাইল বা ডিরেক্টরি নেই" প্রতিবেদন করে। একাধিক শুরুর পয়েন্ট সহ, find
এখনও কিছু কার্যকর ফলাফল ফিরে আসতে পারে এবং কাজ করতে প্রদর্শিত হতে পারে। উদাহরণস্বরূপ, যদি a
এবং c
উপস্থিত থাকে তবে b
থাকে না তবে find a b c -name x
ফলাফল মুদ্রণ করে a
, তারপরে "এরকম কোনও ফাইল বা ডিরেক্টরি নেই" b
, তারপরে ফলাফল c
।
Stdout এবং stderr একসাথে stdout এ মিশ্রন করা এবং এটিgrep
বা অন্য কোনও কমান্ডের সাথে এটি ফিল্টার করার জন্য পাইপিং করা unin যেমন 2>&1 | grep ...
বা |& grep ...
অনিচ্ছাকৃতভাবে কোনও ফাইল ফিল্টার করার ঝুঁকি রয়েছে যার নামটিতে বার্তা ফিল্টার হচ্ছে।
উদাহরণস্বরূপ, যদি আপনি "অনুমতি প্রত্যাখ্যান করে" এমন লাইনগুলি ফিল্টার করেন তবে আপনি "অনুমতি প্রত্যাখ্যানকৃত বার্তা। টেক্সট" এর মতো ফাইলের নাম দেখিয়ে অনুসন্ধানের ফলাফলও ফেলে দেবেন। এটি সম্ভবত দুর্ঘটনাক্রমে ঘটবে, যদিও আপনার অনুসন্ধানগুলিকে ব্যর্থ করার জন্য কোনও ফাইলকে একটি বিশেষভাবে কারুকৃত নাম দেওয়াও সম্ভব হবে।
সংযুক্ত স্ট্রিমগুলি ফিল্টার করার ক্ষেত্রে আরও একটি সমস্যা রয়েছে, যা আরও নির্বাচন করে ফিল্টার করে প্রশমিত করা যায় না (যেমন grep -vx 'find: .*: Permission denied'
পাইপের ডানদিকে রয়েছে)। আপনি কোনও অ্যাকশন নির্দিষ্ট না করার সময় find
অন্তর্ভুক্ত এমন -print
অ্যাকশন সহ কিছু ক্রিয়া stdout টার্মিনাল কিনা তা নির্ভর করে কীভাবে ফাইলনাম আউটপুট করবেন তা নির্ধারণ করে ।
- যদি এটি টার্মিনাল না হয় তবে ফাইলনেমগুলি যেমন আউটপুট হয় তেমনই তাদের মধ্যে নিউলাইনস এবং নিয়ন্ত্রণ অক্ষরগুলির মতো অদ্ভুত অক্ষর থাকে যা আপনার টার্মিনালের আচরণ পরিবর্তন করতে পারে। যদি হয় একটি টার্মিনাল, তারপর এই অক্ষরগুলি দমন করা হয় এবং
?
পরিবর্তে ছাপা হয়।
- এটি সাধারণত আপনি চান আপনি যদি ফাইলের নামগুলি আরও প্রক্রিয়া করতে চলেছেন তবে সেগুলি আক্ষরিকভাবে আউটপুট হতে হবে। তবে, আপনি যদি এগুলি প্রদর্শন করতে চলেছেন তবে একটি নতুন লাইনযুক্ত ফাইলের নামটি অন্যথায় একাধিক ফাইলের নাম অনুকরণ করতে পারে এবং ব্যাকস্পেস অক্ষরের ক্রমযুক্ত একটি ফাইলের নাম একটি আলাদা নাম হিসাবে উপস্থিত হতে পারে। অন্যান্য সমস্যাগুলিও সম্ভব, যেমন আপনার টার্মিনালের রঙ পরিবর্তন করে এমন এস্কেপ সিকোয়েন্সযুক্ত ফাইলের নাম।
- কিন্তু অনুসন্ধানের ফলাফলগুলিকে অন্য কমান্ডের (যেমন
grep
) মাধ্যমে পাইপ দেওয়ার ফলে find
টার্মিনাল আর দেখা যায় না। (আরও সুনির্দিষ্টভাবে বলা যায়, এটি তার স্টাডাউটটি টার্মিনাল না হওয়ার কারণ করে Then তবে যদি পাইপের ডানদিকে থাকা সমস্ত কমান্ডটি হ'ল (ক) "অনুমতি প্রত্যাখ্যান" বার্তাগুলির মতো দেখতে পাওয়া লাইনগুলি সরিয়ে এবং (খ) কী বাকী মুদ্রণ করে, তবে আপনি এখনও সেই শেনানিগানের ধরণের find
টার্মিনালের সাপেক্ষে সনাক্তকরণ প্রতিরোধ উদ্দেশ্যে করা হয়।
man find
ফাইলের নাম মুদ্রিত প্রতিটি ক্রিয়াকলাপের আচরণ সহ আরও তথ্যের জন্য UNUSUAL FILENAMES বিভাগটি দেখুন । ( "অন্যান্য ব্যবহারকারীর নিয়ন্ত্রণাধীন ডেটা মুদ্রণের ফলাফলগুলির অনেকগুলি ক্রিয়াকলাপ ..." ) জিএনইউ ফাইন্ডুইটালস রেফারেন্স ম্যানুয়ালির ৩.৩.২.১ , ৩.৩.২.২ , এবং ৩.৩.২.৩ ও দেখুন ।
অস্বাভাবিক ফাইল নামগুলির উপরের আলোচনাটি জিএনইউ অনুসন্ধানের সাথে সম্পর্কিত , যা find
উবুন্টু সহ জিএনইউ / লিনাক্স সিস্টেমে বাস্তবায়ন।
স্ট্যান্ডার্ড ত্রুটি ফিল্টার করার সময় স্ট্যান্ডার্ড আউটপুট একা রেখে দেওয়া
আপনি কি সত্যিই এখানে চাই ছেড়ে চলে যেতে হয় stdout- এ সময় বংশীধ্বনিতুল্য অক্ষত দ্বারা stderr করতে grep
। দুর্ভাগ্যক্রমে এর জন্য কোনও সহজ বাক্য গঠন নেই। |
পাইপ stdout, এবং কিছু শেল (সহ bash
) |&
উভয় প্রবাহকে পাইপ করতে সহায়তা করে you বা আপনি স্ট্ডারকে প্রথমে স্টডআউটে পুনর্নির্দেশ করতে পারেন 2>&1 |
, যার একই প্রভাব রয়েছে। তবে সাধারণত ব্যবহৃত শেলগুলি কেবল পাইপ স্ট্যাডারকে সিনট্যাক্স সরবরাহ করে না।
আপনি এখনও এটি করতে পারেন। এটা ঠিক বিশ্রী। একটি উপায় হ'ল স্ট্ডারকে স্টেডার দিয়ে অদলবদল করা , যাতে অনুসন্ধান ফলাফলগুলি স্ট্ডারে থাকে এবং ত্রুটিগুলি স্টাডআউটে থাকে, তারপরে grep
ফিল্টারিংয়ের জন্য পাইপ স্টাডাউট :
find args 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied'
সাধারণত আপনি আর্গুমেন্টগুলি find
যেমন পয়েন্টগুলি (অনুসন্ধানের স্থানগুলি যা সাধারণত ডিরেক্টরি) এবং ভবিষ্যদ্বাণী (পরীক্ষা এবং ক্রিয়া) এর কাছে পাস করবেন । এগুলি args
উপরের জায়গায় যায় ।
একটি নতুন প্রবর্তনের দ্বারা এই কাজ ফাইল বর্ণনাকারী , দুই মান স্ট্রিম আপনি অদলবদল করতে চান এক সম্মুখের রাখা তাদের অদলবদল করার পুনঃনির্দেশগুলি করণ, এবং নতুন ফাইল বর্ণনাকারী বন্ধ।
- ফাইল বর্ণনাকারী 1 stdout- এ হল এবং 2 দ্বারা stderr (এবং unredirected 0 stdin )। তবে আপনি অন্যান্য ফাইল বর্ণনাকারী ব্যবহার করে পুনঃনির্দেশ করতে পারেন। এটি কোনও ফাইল বা ডিভাইস খোলার জন্য বা খোলা রাখতে ব্যবহার করা যেতে পারে।
3>&1
ফাইল ডেস্ক্রিপ্টর 3 স্টাডাউটে পুনর্নির্দেশ করে, যাতে পরবর্তী সময়ে যখন স্টডআউট (ফাইল ডেস্ক্রিপ্টর 1) পুনঃনির্দেশিত হয়, মূল স্ট্ডআউটটি এখনও সহজেই লেখা যায়।
1>&2
স্টাডাউটকে স্টার্ডারে পুনঃনির্দেশ করে। ফাইল বিবরণী 3 যেহেতু এখনও মূল স্টডআউট, এখনও এটি অ্যাক্সেস করা যায়।
2>&3
স্ট্যাডারকে ডেস্ক্রিপ্টর 3 এ পুনর্নির্দেশ করে যা মূল স্টডআউট।
3>&-
ফাইল বর্ণনাকারী 3 বন্ধ করে দেয়, যার আর প্রয়োজন হয় না।
- আরও তথ্যের জন্য, stderr পাইপ কীভাবে করবেন, এবং স্টাডাউট নয়? এবং IO পুনঃনির্দেশ - অদলবদল এবং stderr (উন্নত) এবং বিশেষত পাইপ শুধুমাত্র একটি ফিল্টার মাধ্যমে stderr ।
যাইহোক, এই পদ্ধতির অসুবিধা রয়েছে যে অনুসন্ধান ফলাফলগুলি স্ট্ডারকে প্রেরণ করা হয় এবং ত্রুটিগুলি স্টাডাউটে প্রেরণ করা হয় । আপনি যদি এই কমান্ডটি সরাসরি একটি ইন্টারেক্টিভ শেলটিতে চালাচ্ছেন এবং পাইপিং বা আউটপুটকে আর পুনর্নির্দেশ না করে থাকেন তবে তা আসলে কোনও বিষয় নয়। তা না হলে সমস্যা হতে পারে। যদি আপনি সেই নির্দেশটি কোনও স্ক্রিপ্টে রেখে দেন এবং তারপরে কেউ (সম্ভবত আপনি, পরে) এর আউটপুটটিকে পুনঃনির্দেশিত করেন বা পাইপ করেন তবে এটি প্রত্যাশার মতো আচরণ করে না ।
সমাধানটি হ'ল স্ট্রিমগুলিকে আউটপুট ফিল্টার করার পরে আবার অদলবদল করা । পাইপলাইনের ডানদিকে উপরে উল্লিখিত একই পুনঃনির্দেশগুলি প্রয়োগ করা এটি অর্জন করবে না, কারণ |
কেবল পাইপ স্টডআউট, তাই পাইপলাইনটির পাশটি কেবল আউটপুট পায় যা মূলত স্ট্ডারকে প্রেরণ করা হয়েছিল (কারণ স্ট্রিমগুলি অদলবদল হয়েছিল) এবং মূলটি নয় stdout আউটপুট। পরিবর্তে, আপনি (
)
উপরের কমান্ডটি একটি সাব-শেল ( সম্পর্কিত ) তে চালাতে ব্যবহার করতে পারেন , তারপরে স্ব্যাপিং পুনর্নির্দেশগুলি প্রয়োগ করুন:
(find args 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied') 3>&1 1>&2 2>&3 3>&-
এটি গ্রুপিং, বিশেষত সাবসেল নয়, এটি এই কাজ করে makes আপনি যদি পছন্দ করেন তবে আপনি এটি ব্যবহার করতে পারেন {
;}
:
{ find args 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied'; } 3>&1 1>&2 2>&3 3>&-
একটি কম জটিল উপায়: প্রক্রিয়া সাবস্টিটিউশন
এটি সমর্থন করতে পারে এমন সিস্টেমে বাশ সহ কয়েকটি শেল (উবুন্টুর মতো জিএনইউ / লিনাক্স সিস্টেমগুলি সহ) আপনাকে প্রক্রিয়া প্রতিস্থাপন সম্পাদন করতে দেয় যা আপনাকে একটি কমান্ড চালানোর অনুমতি দেয় এবং এর একটি প্রবাহে / থেকে পুনঃনির্দেশ করতে দেয়। আপনি find
কমান্ডের স্ট্ডারকে একটি grep
কমান্ডে পুনর্নির্দেশ করতে পারেন যা এটি ফিল্টার করে এবং সেই grep
কমান্ডের স্টডআউটকে স্টার্ডারে পুনঃনির্দেশ করতে পারে।
find args 2> >(grep -Fv 'Permission denied' >&2)
এই ধারণার জন্য ক্রেডিট অ্যান্ড্রয়েড দেবের কাছে যায় ।
যদিও প্রক্রিয়া প্রতিস্থাপন bash
সমর্থন , sh
উবুন্টু হয় dash
, যা না। আপনি যদি এই পদ্ধতিটি ব্যবহার করার চেষ্টা করেন এটি আপনাকে "সিনট্যাক্স ত্রুটি: পুনর্নির্দেশ অপ্রত্যাশিত" দেবে, যেখানে স্টাডআউট এবং স্ট্ডার অদলবদলের পদ্ধতিটি এখনও কাজ করবে। তদ্ব্যতীত, যখন পসিক্স মোডেbash
চলে তখন প্রক্রিয়া প্রতিস্থাপনের জন্য সমর্থন বন্ধ করা হয়।
bash
POSIX মোডে চলে এমন একটি পরিস্থিতি যখন এটি sh
1 হিসাবে ডাকা হয় । অতএব, ফেডোরার মতো একটি ওএসে যেখানে bash
সরবরাহ করা হয় /bin/sh
বা আপনি যদি উবুন্টুতে /bin/sh
সিমলিংক পয়েন্টটি তৈরি করে bash
থাকেন sh
, তখন পসিক্স মোড বন্ধ করার পূর্ববর্তী কমান্ড ব্যতীত প্রক্রিয়া প্রতিস্থাপন কোনও স্ক্রিপ্টে কাজ করে না । আপনার সেরা বাজি, যদি আপনি কোনও স্ক্রিপ্টে এই পদ্ধতিটি ব্যবহার করতে চান তবে যদি আপনি ইতিমধ্যে না থাকেন তবে তার পরিবর্তে #!/bin/bash
শীর্ষে রাখা উচিত #!/bin/sh
।
1 : এই পরিস্থিতিতে, এটি প্রারম্ভের স্ক্রিপ্টগুলিতে কমান্ডগুলি চালনার পরেbash
স্বয়ংক্রিয়ভাবে পসিক্স মোড চালু করে।
একটি উদাহরণ
এই আদেশগুলি পরীক্ষা করতে সক্ষম হওয়াই দরকারী। এটি করার জন্য, আমি tmp
বর্তমান ডিরেক্টরিটির একটি উপ-ডিরেক্টরি তৈরি করেছি এবং এটিকে "অনুমতি অস্বীকার" ত্রুটিটি ট্রিগার করার জন্য তাদের মধ্য থেকে অনুমতি গ্রহণ করে কিছু ফাইল এবং ডিরেক্টরি দিয়ে এটি তৈরি করি find
।
mkdir tmp; cd tmp; mkdir a b c; touch w a/x 'a/Permission denied messages.txt' b/y c/z; chmod 0 b
ডিরেক্টরি যে এক হয় প্রবেশযোগ্য সঙ্গে "অনুমতি অস্বীকৃত" তার নাম একটি ফাইল অন্তর্ভুক্ত করা হয়েছে। find
কোনও পুনঃনির্দেশ বা পাইপ না দিয়ে চালানো এই ফাইলটি দেখায়, তবে অ্যাক্সেসযোগ্য নয় এমন অন্য ডিরেক্টরিটির জন্য প্রকৃত "অনুমতি অস্বীকার" ত্রুটিও দেখায় :
ek@Io:~/tmp$ find
.
./a
./a/Permission denied messages.txt
./a/x
./c
./c/z
./w
./b
find: ‘./b’: Permission denied
Stdout এবং stderr উভয়কে পাইপ দেওয়া grep
এবং "অনুমতি অস্বীকার করা" রয়েছে এমন লাইনগুলিকে ফিল্টার করা ত্রুটি বার্তাটি দূরে সরিয়ে দেয় তবে ফাইলটির সন্ধানের ফলাফলটিকে তার নামে এই বাক্যাংশটিও আড়াল করে:
ek@Io:~/tmp$ find |& grep -Fv 'Permission denied'
.
./a
./a/x
./c
./c/z
./w
./b
find 2>&1 | grep -Fv 'Permission denied'
সমতুল্য এবং একই আউটপুট উত্পাদন করে।
অনুসন্ধানের ফলাফল থেকে নয় - কেবল ত্রুটি বার্তাগুলি থেকে "অনুমতি অস্বীকৃত" ফিল্টার আউট করার জন্য উপরে প্রদর্শিত পদ্ধতিগুলি সফল। উদাহরণস্বরূপ, স্টাডাউট এবং স্ট্ডার অদলবদল করার পদ্ধতিটি এখানে:
ek@Io:~/tmp$ (find 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied') 3>&1 1>&2 2>&3 3>&-
.
./a
./a/Permission denied messages.txt
./a/x
./c
./c/z
./w
./b
find args 2> >(grep -Fv 'Permission denied' >&2)
একই আউটপুট উত্পাদন করে।
আপনি যে লাইন stderr হবে পাঠিয়েছে যা নিশ্চিত করার একটি ভিন্ন ত্রুটির বার্তা আরম্ভ করতে পারবেন না পাঠ্য "এর অনুমতি অস্বীকার করেছেন" থাকতেই এখনো মাধ্যমে অনুমতি দেওয়া হয়। উদাহরণস্বরূপ, এখানে আমি find
বর্তমান ডিরেক্টরিটি ( .
) একটি চালানো পয়েন্ট foo
হিসাবে চালিয়েছি তবে অন্যটির মতো অস্তিত্বের ডিরেক্টরি :
ek@Io:~/tmp$ (find . foo 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied') 3>&1 1>&2 2>&3 3>&-
.
./a
./a/Permission denied messages.txt
./a/x
./c
./c/z
./w
./b
find: ‘foo’: No such file or directory
find
এর স্ট্যান্ডার্ড আউটপুট চেক করা এখনও একটি টার্মিনাল
আমরা দেখতে পাচ্ছি কোন কমান্ডের কারণে বিশেষ অক্ষর যেমন নিউলাইনগুলি আক্ষরিকভাবে প্রদর্শিত হয়। (এটি উপরোক্ত প্রদর্শন থেকে আলাদাভাবে করা যেতে পারে এবং এটি tmp
ডিরেক্টরিতে থাকা প্রয়োজন হয় না ))
নামে একটি নতুন লাইন দিয়ে একটি ফাইল তৈরি করুন:
touch $'abc\ndef'
সাধারণত আমরা ডিরেক্টরিগুলি সূচনা পয়েন্ট হিসাবে ব্যবহার করি find
তবে ফাইলগুলিও কাজ করে:
$ find abc*
abc?def
অন্য কমান্ড stdout- এ বংশীধ্বনিতুল্য ঘটায় সম্পর্কে newline আক্ষরিক outputted হবে, এর দুটি পৃথক সন্ধানের ফলাফলের মিথ্যা ছাপ তৈরি abc
এবং def
। আমরা এটি দিয়ে পরীক্ষা করতে পারি cat
:
$ find abc* | cat
abc
def
কেবল স্টাডারকে পুনঃনির্দেশ করা এই সমস্যার কারণ নয়:
$ find abc* 2>/dev/null
abc?def
বা এটি বন্ধ করে না:
$ find abc* 2>&-
abc?def
থেকে বংশীধ্বনিতুল্য grep
করে সমস্যা কারণ:
$ find abc* |& grep -Fv 'Permission denied'
abc
def
(প্রতিস্থাপন |&
সঙ্গে 2>&1 |
সমতূল্য এবং একই আউটপুট উত্পাদন করে।)
Stdout এবং stderr এবং পাইপিং stdout অদলবদল সমস্যা সৃষ্টি করে না st find
এর stdout stderr, যা পাইপ করা হয় না :
$ find abc* 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied'
abc?def
এই কমান্ডকে দলবদ্ধ করে স্ট্রিমগুলি আবার অদলবদল করতে সমস্যা তৈরি করে না:
$ (find abc* 3>&1 1>&2 2>&3 3>&- | grep -Fv 'Permission denied') 3>&1 1>&2 2>&3 3>&-
abc?def
( {
;}
সংস্করণ একই আউটপুট উত্পাদন করে।)
স্ট্যাডার ফিল্টার করার জন্য প্রক্রিয়া বিকল্প ব্যবহার করা সমস্যার কারণ হয় না:
$ find abc* 2> >(grep -Fv 'Permission denied' >&2)
abc?def