সন্ধান করুন: -মুগ্ধের পক্ষে অনুপস্থিত যুক্তি


206

আমাকে আজ একটি কমান্ড দিয়ে সাহায্য করা হয়েছিল, তবে এটি কাজ করছে বলে মনে হয় না। এই হুকুম:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {}\;

খোল ফিরে আসে

find: missing argument to `-exec'

আমি মূলত যা করার চেষ্টা করছি তা হ'ল ডিরেক্টরিটি পুনরাবৃত্তভাবে (যদি এর অন্যান্য ডিরেক্টরি থাকে) দিয়ে যায় এবং .rmফাইল প্রকারে ffmpeg কমান্ড চালিয়ে তাদের ফাইলের ধরণে রূপান্তর করে .mp3। এটি হয়ে গেলে, .rmসবে রূপান্তরিত হওয়া ফাইলটি সরিয়ে ফেলুন ।

আমি এই বিষয়ে কোন সাহায্যের প্রশংসা করি।

উত্তর:


340

একটি -execকমান্ড একটি দিয়ে শেষ করা করা আবশ্যক ;(তাই আপনি সাধারণত টাইপ করতে হবে \;অথবা ';'বা শেল দ্বারা এড়ানোর interpretion করার জন্য) +। পার্থক্যটি হ'ল ;, ফাইলটি প্রতি কমান্ডটি একবার কল করা হয়, সাথে +এটি একেবারে কম কয়েকবার বলা হয় (সাধারণত একবার হলেও কমান্ড লাইনের সর্বাধিক দৈর্ঘ্য থাকে, তাই এটি বিভক্ত হতে পারে) সমস্ত ফাইলের সাথে । এই উদাহরণটি দেখুন:

$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two

আপনার আদেশের দুটি ত্রুটি রয়েছে:

প্রথমত, আপনি ব্যবহার করেন {};তবে ;অবশ্যই এটির নিজস্ব একটি প্যারামিটার হওয়া উচিত।

দ্বিতীয়ত, কমান্ডটি শেষ হয় &&। আপনি "রান ফাইন্ড" নির্দিষ্ট করেছেন এবং যদি এটি সফল হয় তবে নামকৃত ফাইলটি সরান {};। আপনি যদি -execকমান্ডের শেল স্টাফ ব্যবহার করতে চান , আপনার এটি স্পষ্টভাবে শেলটিতে চালানো দরকার, যেমন -exec sh -c 'ffmpeg ... && rm'

তবে আপনার বাশ কমান্ডের মধ্যে {add যুক্ত করা উচিত নয়, বিশেষ অক্ষরগুলি উপস্থিত থাকলে এটি সমস্যা তৈরি করবে। পরিবর্তে, আপনি শেলের অতিরিক্ত পরামিতিগুলি পরে -c command_string(দেখুন man sh) পাস করতে পারেন :

$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)

আপনি $প্রথম উদাহরণে শেলটি দিয়ে জিনিসটি মূল্যায়ন করে দেখুন। কল করুন $(rm -rf /):-) নামে একটি ফাইল রয়েছে

(পার্শ্ব নোট: -প্রয়োজন নেই, তবে কমান্ডটি ভেরিয়েবলের পরে নির্ধারিত হওয়ার পরে প্রথম ভেরিয়েবল $0, যা একটি বিশেষ ভেরিয়েবল যা সাধারণত প্রোগ্রামটি চালিত হয় এবং একটি প্যারামিটারে সেট করা কিছুটা অপরিষ্কার, যদিও এটি জিতেছিল সম্ভবত এখানে কোনও ক্ষতির কারণ হবে না, তাই আমরা সেটাকে ঠিক করে -দিয়ে শুরু করি $1))

সুতরাং আপনার আদেশ কিছু হতে পারে

find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;

কিন্তু একটি ভাল উপায় নেই। সমর্থন সন্ধান করুন andএবং or, যাতে আপনি পছন্দসই জিনিসগুলি করতে পারেন find -name foo -or -name bar। তবে এটি এর সাথেও কাজ করে -exec, যা কমান্ডটি সফলভাবে প্রস্থান করা হলে সত্য হিসাবে মূল্যায়ন করে এবং যদি না হয় তবে এটি মিথ্যা হয়। এই উদাহরণটি দেখুন:

$ ls
false  true
$ find * -exec {} \; -and -print
true

এটি কেবল মুদ্রণটি চালায় যদি কমান্ডটি সফলভাবে হয়, যা এটির জন্য হয়েছিল trueতবে এটির জন্য নয় false

সুতরাং আপনি একটি দ্বারা শৃঙ্খলিত দুটি -andএক্সিকিউটমেন্ট বিবৃতি ব্যবহার করতে পারেন , এবং এটি কেবল পরে কার্যকর করা হয় যদি প্রাক্তন সফলভাবে চালানো হয়।


3
মূলটি মনে হয় মারিয়ানের লাইনটি "দ্যা; এটি নিজেরাই একটি যুক্তি" যা আমার জন্য, লাইটবাল্ব বুদ্ধিমান এবং আমার কোড নমুনার জন্য এটি করেছিল। ধন্যবাদ।
pjammer

3
এটি অন-এক্সেক-এ পড়েছি সেরা বর্ণনা সম্পর্কে। এটি অত্যন্ত শক্তিশালী তবে এটির জন্য সঠিক বাক্য গঠন পাওয়া আমার পক্ষে সবসময়ই কঠিন। এটি কয়েকটি বিষয়কে আরও পরিষ্কার করে দিয়েছে। বিশেষ করে পৃথক শেল কমান্ড মোড়ানো। খুশী হলাম। ধন্যবাদ।
ইউরোস্পুফার

3
নোট করুন -andএবং -orপোর্টেবল নয়। পসিক্স নির্দিষ্ট করে -aএবং-o এবং প্রকৃতপক্ষে -aসর্বদা অনুমান করা হয় (অতএব প্রয়োজন হয় না)।
gniourf_gniourf

এছাড়াও টার্মিনেটরের আগে অবশ্যই একটি স্থান থাকতে হবে। প্রাক্তন "\;"কাজ করে না তবে " \;"করে
frmdstryr

56

আমি এখন এটি সন্ধান। যখন আপনাকে একটি অনুসন্ধানে এক্সিকিউটে দুটি কমান্ড চালানোর দরকার হয় তখন আপনাকে দুটি পৃথক এক্সিকিউট করতে হবে। এই অবশেষে আমার জন্য কাজ করে।

find . -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 \; -exec rm {} \;

এটি মুছে ফেলার ফাইলের ভেরিয়েবলটি পাবেন কিনা তা নিশ্চিত নন? কেউ কি জানেন যদি এই ঘটনাটি ঘটে?
আবস

7
এই জাতীয় জিনিসগুলি পরীক্ষা echoকরতে কমান্ডগুলির আগে একটি যুক্ত করুন এবং দেখুন এটি কী করে।
মারিয়ান

2
@ মারিয়ান, echoবেশ অবিশ্বাস্য - আপনি echo "one argument"এবং এর মধ্যে পার্থক্য বলতে পারবেন না echo one argument(পরেরটির আউটপুটটি মিথ্যা হচ্ছে, কারণ এটি আসলে echoদুটি সম্পূর্ণ পৃথক যুক্তি পাস করছে )। এর মতো আরও কিছু করা আরও ভাল -exec bash -c 'printf "%q " "$@"' _ ffmpeg -i {} -sameq {}.mp3 \; -printf '\n', যা আউটপুট এমনভাবে মুদ্রণ করবে যা ছাপিয়ে যায় না এমন অক্ষরগুলিকে দৃশ্যমান করে তোলে যাতে আপনি ডস নিউলাইন এবং অন্যান্য বিজোড়তা সনাক্ত করতে পারেন।
চার্লস ডাফি

52

প্রতিটি before এর আগে একটি স্থান রাখার চেষ্টা করুন;

কাজ করে:

find . -name "*.log" -exec echo {} \;

কাজ করে না:

find . -name "*.log" -exec echo {}\;

1
এটি আমাকে প্রায়শই ট্রিপ করে। এই দিনগুলির মধ্যে একটি, আমি ডিফল্টরূপে একটি স্থান যুক্ত করব।
হার্পারভিল

আমার জন্য এটি সাইগউইনের উইন্ডোজ 7 এর ঠিক বিপরীতে কাজ করে: \ এর আগে কোনও স্থান নেই; কাজ করে, স্থান সহ - না। তবে আমি যদি আগে before সরিয়ে ফেলি; এটি কাজ করে, এবং আগে জায়গা ছাড়াই; এটি এখানে বর্ণিতভাবেই হয় না।
ওয়েবকোমার

7

কেবল আপনার তথ্যের জন্য:
আমি একটি সাইগউইন সিস্টেমে "ফাইন্ড-এক্সেক" কমান্ডটি ব্যবহার করার চেষ্টা করেছি (উইন্ডোজে ইউনিক্স অনুকরণ করা), এবং সেখানে মনে হচ্ছে সেমিকোলনটি সরিয়ে দেওয়ার আগে ব্যাকস্ল্যাশ অবশ্যই অপসারণ করতে হবে:
find ./ -name "blabla" -exec wc -l {} ;


আমি সত্যিই বিভ্রান্ত। find /etc/nginx -name '*.conf' -exec echo {} ;এবং find /etc/nginx -name '*.conf' -exec echo {}\;একই ফলাফল দিয়েছে। :(
কারবি

উইন্ডোজের জন্য গিট নিয়ে আসা বাশ শেলটি আমি চালাচ্ছি এবং ডাস্টিন কাউলেস উত্তর আমার পক্ষে কাজ করে। অন্য কথায়: কোনও উদ্ধৃতি নেই, ব্যাকস্ল্যাশ সেমিকোলন দ্বারা পালিয়ে গেছে, পরে স্থান {}
ম্যাকডন

অর্থের কোনও পার্থক্য নেই, তবে কিছু ক্ষেত্রে আপনাকে ব্যাকস্ল্যাশ লাগাতে হবে, কিছু ক্ষেত্রে আপনি এটি রাখতে পারবেন না এবং আবার অন্য ক্ষেত্রে আপনি বেছে নিতে পারেন।
ডোমিনিক

2

অ্যামাজন অপসওয়ার্স শেফ বাশ স্ক্রিপ্টগুলিতে যে কোনও "অনুরূপ" অনুপস্থিত-এক্সেক আরগস "দেখতে পাওয়া যায়, সেই ক্ষেত্রে escape এড়াতে আমাকে আরও একটি ব্যাকস্ল্যাশ যুক্ত করতে হবে;

bash 'remove_wars' do
  user 'ubuntu'
  cwd '/'
  code <<-EOH
    find /home/ubuntu/wars -type f -name "*.war" -exec rm {} \\;
  EOH
  ignore_failure true
end

2

এছাড়াও, যদি অন্য কারও কাছে "অনুসন্ধান: অনুপস্থিত আর্গুমেন্টটি খুঁজে পাওয়া যায়" এটির সাহায্য করে:

কিছু শেলের মধ্যে আপনার পালানোর দরকার নেই, অর্থাত ""; "এর সামনে আপনার" \ "দরকার নেই।

find <file path> -name "myFile.*" -exec rm - f {} ;

2
এখানে ;উদ্ধৃত না হওয়া বা পলায়ন না হওয়ার অর্থ এটি শেল দ্বারা গ্রাস করা যেতে পারে, পড়ে না find। এছাড়াও, -fএবং - fদুটি ভিন্ন জিনিস।
চার্লস ডাফি


0

কমান্ড লাইন দ্বারা প্রসারিত হওয়ার কারণে &} এবং&& উভয়ই সমস্যা সৃষ্টি করবে। আমি চেষ্টা করার পরামর্শ দেব:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i \{} -sameq \{}.mp3 \; -exec rm \{} \;

এক্সিকিউটে প্রথম কমান্ডটি যদি সফল হয় এবং এক্সিকিউটে দ্বিতীয় কমান্ড কার্যকর হয়, তবে কি এখনও {}সঠিক ফাইলটি মুছতে ভেরিয়েবলের অ্যাক্সেস থাকবে ?
আবস

আপনি কি থোনিক {}প্রসারিত করবেন? যদি না এটিতে দুটি বিন্দু বা কমা থাকে যা এটি যেমন থাকবে তেমন থাকবে।
মারিয়ান

0

আপনাকে {}এবং এর মধ্যে একটি জায়গা রাখতে হবে\;

কমান্ডটি এর মতো হবে:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {} \;

-4

যদি আপনি এখনও "সন্ধান করুন: অনুপস্থিত আর্গুমেন্ট টু-এক্সেক" পেয়ে যাচ্ছেন তবে উদ্ধৃতিগুলিতে এক্সিকিউট আর্গুমেন্ট মোড়ানোর চেষ্টা করুন।

find <file path> -type f -exec "chmod 664 {} \;"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.