শেল ফাইলনাম প্যাটার্ন যা ডট ফাইলগুলিতে প্রসারিত কিন্তু `..`?


13

শেল প্যাটার্নের কারণে সম্প্রতি আমার একটি সামান্য বিপর্যয় ঘটেছিল যা অপ্রত্যাশিতভাবে প্রসারিত হয়েছিল। আমি /rootডিরেক্টরিতে ডট ফাইলগুলির একগুচ্ছের মালিককে পরিবর্তন করতে চেয়েছিলাম , তাই আমিও করেছি

chown -R root .*

স্বভাবতই, এতে .*প্রসারিত হয়েছিল ..যা কিছুটা বিপর্যয় হয়েছিল।

আমি জানি bashএই আচরণ কিছু শেল বিকল্প tweaking দ্বারা পরিবর্তন করা যাবে, কিন্তু ডিফল্ট সেটিংস দিয়ে কোন প্যাটার্ন ডিরেক্টরিটি প্রতিটি বিন্দু ফাইল প্রসারিত কিন্তু নয় .এবং ..?

উত্তর:


20

বাশ, ksh এবং zsh এর আরও ভাল সমাধান রয়েছে তবে এই উত্তরে আমি একটি পসিক্স শেল অনুমান করি।

প্যাটার্ন .[!.]*সব ফাইল একটি বিন্দু দিয়ে শুরু একটি অ-ডট অক্ষর দ্বারা অনুসৃত সাথে মেলে। (নোট যে [^.]কিছু শাঁস দ্বারা সমর্থিত তবে সব নয় ওয়াইল্ডকার্ড ধরনে অক্ষর সেট সম্পূরক জন্য পোর্টেবল সিনট্যাক্স হয় [!.]।) সুতরাং বাদ .এবং .., কিন্তু ফাইল দুটি বিন্দুর দিয়ে শুরু। প্যাটার্নটি ..?*ফাইলগুলি পরিচালনা করে যা দুটি বিন্দু দিয়ে শুরু হয় এবং কেবল তা নয় ..

chown -R root .[!.]* ..?*

এটি সমস্ত ফাইলের সাথে মিলে যাওয়ার জন্য শাস্ত্রীয় প্যাটার্নটি সেট করা আছে:

* .[!.]* ..?*

এই পদ্ধতির একটি সীমাবদ্ধতা হ'ল যদি কোনও নিদর্শন কোনওটির সাথে মেলে না, তবে এটি কমান্ডে প্রেরণ করা হবে। একটি স্ক্রিপ্টে, আপনি যখন কোনও ডিরেক্টরিতে সমস্ত ফাইলের সাথে মিল করতে চান .এবং ..এর বাইরেও বেশ কয়েকটি সমাধান রয়েছে, সেগুলি সবগুলিই জটিল:

  • ব্যবহারের * .*সমস্ত এন্ট্রি গনা, এবং অগ্রাহ্য .এবং ..একটি লুপ হবে। এক বা উভয় নিদর্শন কিছুই মিলতে পারে না, সুতরাং লুপ প্রতিটি ফাইলের অস্তিত্ব জন্য পরীক্ষা করা প্রয়োজন। আপনার অন্যান্য মানদণ্ডে ফিল্টার করার সুযোগ রয়েছে; উদাহরণস্বরূপ, -hযদি আপনি ঝুঁকির প্রতীকী লিঙ্কগুলি এড়িয়ে যেতে চান তবে পরীক্ষাটি সরিয়ে ফেলুন ।

    for x in * .*; do
      case $x in .|..) continue;; esac
      [ -e "$x" ] || [ -h "$x" ] || continue
      somecommand "$x"
    done
  • আরও জটিল বৈকল্পিক যেখানে কমান্ডটি একবারে চালিত হয়। নোট করুন যে অবস্থানগত পরামিতিগুলি ক্লোবারযুক্ত (পসিক্স শেলগুলিতে অ্যারে নেই); এটি যদি কোনও সমস্যা হয় তবে এটি একটি পৃথক ফাংশনে রাখুন।

    set --
    for x in * .[!.]* ..?*; do
      case $x in .|..) continue;; esac
      [ -e "$x" ] || [ -h "$x" ] || continue
      set -- "$@" "$x"
    done
    somecommand "$@"
  • * .[!.]* ..?*ট্রিপটাইচ ব্যবহার করুন । আবার এক বা একাধিক নিদর্শনগুলির সাথে কিছু মিলতে পারে না, সুতরাং আমাদের বিদ্যমান ফাইলগুলি (প্রতীকী লিঙ্কগুলিতে ঝাঁকুনি সহ) পরীক্ষা করতে হবে।

    for x in * .[!.]* ..?*; do
      [ -e "$x" ] || [ -h "$x" ] || continue
      somecommand "$x"
    done
  • * .[!.]* ..?*ট্রিপটিচটি ব্যবহার করুন এবং প্রতি প্যাটার্নে একবারে কমান্ডটি চালান তবে কেবল এটির সাথে কিছু মিলছে। এটি কমান্ডটি একবার চালায়। নোট করুন যে অবস্থানগত পরামিতিগুলি ক্লোবারযুক্ত (POSIX শেলগুলিতে অ্যারে নেই), এটি কোনও সমস্যা হলে এটি একটি পৃথক ফাংশনে রাখুন।

    set -- *
    [ -e "$1" ] || [ -h "$1" ] || shift
    set -- .[!.]* "$@"
    [ -e "$1" ] || [ -h "$1" ] || shift
    set -- ..?* "$@"
    [ -e "$1" ] || [ -h "$1" ] || shift
    somecommand "$@"
  • ব্যবহার find। গনুহ বা বাসদ খোঁজ সঙ্গে, পুনরাবৃত্তির এড়ানো বিকল্প সহ সহজ -mindepthএবং -maxdepth। পসিক্স সন্ধানের সাহায্যে এটি কিছুটা কৌতুকপূর্ণ তবে এটি করা যায়। এই ফর্মটিতে সহজেই ফাইল প্রতি একবারের পরিবর্তে একবারে কমান্ডটি চালানোর অনুমতি দেওয়ার সুবিধা রয়েছে (তবে এটির গ্যারান্টিযুক্ত নয়: যদি ফলাফল প্রাপ্ত কমান্ডটি দীর্ঘ হয় তবে কমান্ডটি বেশ কয়েকটি ব্যাচে চালানো হবে)।

    find . -name . -o -exec somecommand {} + -o -type d -prune

6

ফাইলের সবগুলিতে কমপক্ষে তিনটি অক্ষর (বিন্দু সহ) থাকলে এটি কাজ করে:

chown -R root .??*

আরও শক্তিশালী সমাধানের জন্য আপনি ব্যবহার করতে পারেন find:

find . -maxdepth 1 -name '.*' -exec chown -R root {} \;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.