ফাইন্ড কমান্ডের ইন-এক্সেক-এ আমি কীভাবে দুটি ব্যাশ কমান্ড ব্যবহার করতে পারি?


32

কমান্ডের -execঅংশে 2 কমান্ড ব্যবহার করা সম্ভব find?

আমি এরকম কিছু চেষ্টা করেছি:

find . -name "*" -exec  chgrp -v new_group {}  ; chmod -v 770 {}  \;

এবং আমি পেয়েছি:

সন্ধান করুন: -exec
chmod- তে আর্গুমেন্ট অনুপস্থিত : {} অ্যাক্সেস করতে পারে না: এই জাতীয় কোনও ফাইল বা ডিরেক্টরি
chmod: অ্যাক্সেস করতে পারে না: এই জাতীয় ফাইল বা ডিরেক্টরি নেই

উত্তর:


44

findকমান্ড হিসাবে , আপনি কেবল -execএক সারি আরও কমান্ড যুক্ত করতে পারেন :

find . -name "*" -exec chgrp -v new_group '{}' \; -exec chmod -v 770 '{}' \;

মনে রাখবেন যে এই আদেশটি তার ফলস্বরূপ, ব্যবহারের সমতুল্য

chgrp -v new_group ফাইল && chmod -v 770 ফাইল

প্রতিটি ফাইলের উপর।

সমস্ত findপ্যারামিটার যেমন , এবং এর মতো -name, আসলে পরীক্ষাগুলি : যতক্ষণ না পুরো চেইনটিকে সত্য হিসাবে মূল্যায়ন করা হয়েছে ততক্ষণ এগুলি একে একে চালিয়ে যেতে থাকবে । সুতরাং প্রতিটি পরপর কমান্ড কেবল তখনই কার্যকর করা হয় যদি পূর্ববর্তীগুলি সত্য হয়ে যায় (অর্থাত্ কমান্ডগুলির প্রস্থান স্থিতি)। কিন্তু লজিক অপারেটরগুলি যেমন বা ( ) এবং না ( ) হিসাবে বোঝে । অতএব, পূর্ববর্তী ফলাফল নির্বিশেষে পরীক্ষার একটি শৃঙ্খলা ব্যবহার করার জন্য , এই জাতীয় কিছু ব্যবহার করা প্রয়োজন:-exec-sizefind-exec0find-o!-exec

find . -name "*" \( -exec chgrp -v new_group {} \; -o -exec chmod -v 770 {} \; \)

4
+1: হ্যাঁ, এটি করার জন্য এটি সবচেয়ে মার্জিত উপায়। আপনি যদি ব্যাখ্যা করতে পারেন, আপনি কেন '{}'(ধনুর্বন্ধনীগুলির চারপাশে অ্যাস্ট্রোফেস
ব্যবহারকারী অজানা

1
@ ব্যবহারকারীর দুর্ভাগ্যক্রমে, আমি জানি না এটি এখনও প্রয়োজনীয় কিনা। আমি এখনই কিছু পরীক্ষা করেছি এবং এমন কোনও পরিস্থিতি আসেনি যা এটির কোনও পরিবর্তন ঘটবে। আমার ধারণা এটি কেবল "ভাল অনুশীলন" যা মরে যাবে।
rozcietrzewiacz

2
তাদের নামে ফাঁকা ফাইলগুলির জন্য উদ্ধৃতিগুলি গুরুত্বপূর্ণ।
nnot101

17
find . -name "*" -exec sh -c 'chgrp -v new_group "$0" ; chmod -v 770 "$0"' {} \;

@ গিলস: -c$ 0 এর বিচিত্র হ্যান্ডলিংয়ের বিস্ময়গুলি আমাকে মনে করে প্রতিবার এটি দেখার জন্য এটি ভুল বলে মনে করে, তবে এটি অবশ্যই সঠিক।
ডার্বোবার্ট

আমি স্পষ্ট শেল সংজ্ঞায়িত করা পছন্দ করি ...
jjofofan

এই উত্তরটি (এবং গিলসের উত্তর) প্রদত্ত প্রশ্নের উত্তরের জন্য ভাল উত্তর বলে মনে হচ্ছে sh -c

14

আপনার কমান্ডটি প্রথমে শেল দ্বারা দুটি কমান্ডকে a দ্বারা বিভক্ত করা হয়েছে ;যা একটি নতুন লাইনের সমতুল্য:

find . -name "*" -exec chgrp -v new_group {}
chmod -v 770 {} \;

আপনি যদি শেল কমান্ডটি চালাতে চান তবে একটি শেলটি স্পষ্টভাবে অনুরোধ করুন bash -c(অথবা sh -cযদি আপনি শেলটি বিশেষভাবে ব্যাশ করে না তবে):

find . -name "*" -exec sh -c 'chgrp -v new_group "$0"; chmod -v 770 "$0"' {} \;

{}শেলের আর্গুমেন্ট হিসাবে ব্যবহারটি নোট করুন ; এটি জিরোথ আর্গুমেন্ট (যা সাধারণত শেল বা স্ক্রিপ্টের নাম, তবে এখানে এখানে কিছু আসে যায় না), তাই হিসাবে উল্লেখ করা হয় "$0"

আপনি একবারে শেলটিতে একাধিক ফাইলের নামগুলি পাস করতে পারেন এবং সেগুলির মাধ্যমে শেলটি পুনরাবৃত্তি করতে পারেন, এটি আরও দ্রুত হবে। এখানে আমি _স্ক্রিপ্টের নাম হিসাবে পাস করি এবং নিম্নলিখিত আর্গুমেন্টগুলি ফাইলের নাম, যা for x(এর জন্য একটি শর্টকাট for x in "$@") পুনরাবৃত্তি হয়।

find . -name "*" -exec sh -c 'for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done' _ {} +

নোট করুন যে বাশ 4, বা zsh এ, আপনার এখানে কোনও সন্ধানের দরকার নেই। বাশে, একটি পুনরাবৃত্ত ডিরেক্টরি গ্লোব জন্য স্থায়ী সক্রিয় করতে চালান shopt -s globstar(এটি আপনার রাখুন ~/.bashrc) **/। (Zsh এ, এটি সর্বদা সক্রিয় থাকে)) তারপরে

chgrp -v new_group -- **/*; chmod -v 770 -- **/*

অথবা আপনি যদি চান ফাইলগুলি ক্রমে পুনরাবৃত্তি করা হোক

for x in **/*; do
  chgrp -v new_group -- "$x"
  chmod -v 770 -- "$x"
done

findকমান্ডের সাথে একটি পার্থক্য হ'ল শেলটি ডট ফাইলগুলিকে উপেক্ষা করে (ফাইলগুলির নাম যার সাথে শুরু হয় a .)। এগুলি অন্তর্ভুক্ত করতে, ব্যাশে, প্রথম সেট GLOBIGNORE=.:..; zsh এ, গ্লোব **/*(D)প্যাটার্ন হিসাবে ব্যবহার করুন ।


এই উত্তরটি (এবং গ্লেনের উত্তর) প্রদত্ত প্রশ্নের উত্তরের জন্য ভাল উত্তর বলে মনে হচ্ছে sh -c
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.