বাশ স্ক্রিপ্টিং: খালি ডিরেক্টরি জন্য পরীক্ষা


95

ডিরেক্টরিতে যদি কোনও ফাইল থাকে না তবে আমি পরীক্ষা করতে চাই। যদি তা হয় তবে আমি কিছু প্রক্রিয়াজাতকরণ এড়িয়ে যাব।

আমি নিম্নলিখিত চেষ্টা করেছিলাম:

if [ ./* == "./*" ]; then
    echo "No new file"
    exit 1
fi

এটি নিম্নলিখিত ত্রুটি দেয়:

line 1: [: too many arguments

কোন সমাধান / বিকল্প আছে?


উত্তর:


120
if [ -z "$(ls -A /path/to/dir)" ]; then
   echo "Empty"
else
   echo "Not Empty"
fi

এছাড়াও ডিরেক্টরিটি আগে উপস্থিত রয়েছে কিনা তা খতিয়ে দেখতে শীতল হবে।


11
ব্যবহার করবেন না &&এবং ||একযোগে! যদি echo "Not Empty"ব্যর্থ হয়, echo "Empty"চালানো হবে! চেষ্টা করুন echo "test" && false || echo "fail"! হ্যাঁ, আমি জানি echoব্যর্থ হবে না তবে আপনি যদি অন্য কোনও আদেশ পরিবর্তন করেন তবে আপনি অবাক হবেন!
uzsolt

4
দয়া করে, উপরের কোডটি যখন কাজ করবে না তখন কমপক্ষে একটি উদাহরণ সরবরাহ করুন। কংক্রিটলি এই কোডটি একেবারে সঠিক। আমি আশা করি যে প্রশ্নকর্তা এটি নিজের উদ্দেশ্যে
এটির

3
[ "$(ls -A /)" ] && touch /non-empty || echo "Empty"- আপনি যদি একটি চিহ্নিত ফাইল নামের খালি খালি ডায়ারগুলিকে "চিহ্নিত" করতে চান non-empty, ব্যর্থ হবে এবং "খালি" মুদ্রণ করবে।
uzsolt

4
কোথায় touch /emptyআমার লাইন কি?
আন্দ্রে আতাপিন

7
ওহ না! এই কোডটিতে একটি খুব গুরুত্বপূর্ণ সমস্যা আছে। এটি হওয়া উচিত if [ -n "$(ls -A /path/to/dir)" ]; then... দয়া করে কেউ এই কোডটি কোথাও তাদের সার্ভারে পেস্ট করার আগে উত্তরটি আপডেট করুন এবং কোনও হ্যাকার কীভাবে এটি ব্যবহার করবেন তা নির্ধারণ করে। যদি /path/to/dirখালি না থাকে, তবে সেখানকার ফাইলের নামগুলি আর্গুমেন্ট হিসাবে পাস হয়ে যায় /bin/testযার স্পষ্টভাবে উদ্দেশ্য হয় না। শুধু -nযুক্তি যুক্ত করুন , সমস্যা সমাধান হয়েছে। ধন্যবাদ!
এডওয়ার্ড নেড হার্ভে

21

কিছু গণনা বা শেল গ্লোব প্রয়োজন হয় না। আপনি readএকসাথে ব্যবহার করতে পারেন find। যদি findআউটপুট খালি থাকে তবে আপনি ফিরে আসবেন false:

if find /some/dir -mindepth 1 | read; then
   echo "dir not empty"
else
   echo "dir empty"
fi

এটি পোর্টেবল হতে হবে।


চমৎকার সমাধান, তবে আমি মনে করি আপনার echoকলগুলি ভুল ফলাফলকে প্রতিফলিত করে: আমার পরীক্ষায় (সাইগউইনের অধীনে) find . -mindepth 1 | readএকটি খালি দির একটি 141 ত্রুটি কোড ছিল, এবং একটি ফাঁকা দির 0 টি ছিল
লুকাস সিমন

@ লুকাসসিমন এখানে নেই (ম্যাকোস এবং জিএনইউ / লিনাক্স)। একটি খালি নয় ডিরেক্টরি জন্য, read0, এবং একটি খালি, 1
ফিরে।

1
পিএসএ এর সাথে কাজ করে নাset -o pipefail
কর্নেল থার্টি টু

19
if [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
    echo "Empty directory"
else
    echo "Not empty or NOT a directory"
fi

সঠিক এবং দ্রুত। নিস!
l0b0

4
এর উদ্ধৃতি (2x) এবং পরীক্ষাটি -nসঠিক এবং নিরাপদ হতে হবে (নামের ফাঁকা জায়গাগুলির সাথে ডিরেক্টরি সহ পরীক্ষা করুন, এটি '0 = 1' নামের ফাঁকা ফাঁকা ডিরেক্টরিতে পরীক্ষা করুন)। ... [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; ...
জ্রিন

1
@ivan_pozdeev এটি সত্য নয়, অন্তত জিএনইউ অনুসন্ধানের জন্য। আপনি ভাবতে পারেন grepserverfault.com/questions/225798/…
ভ্লাদিমির

এটি লিখতে সহজ হতে পারে find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty | grep .এবং গ্রেপ থেকে প্রস্থান স্থিতির উপর নির্ভর করে। আপনি যেভাবেই এটি করেন না কেন এটি এই প্রশ্নের সঠিক উত্তর।
টম অ্যান্ডারসন

13
#!/bin/bash
if [ -d /path/to/dir ]; then
    # the directory exists
    [ "$(ls -A /path/to/dir)" ] && echo "Not Empty" || echo "Empty"
else
    # You could check here if /path/to/dir is a file with [ -f /path/to/dir]
fi

4
এটি অবশ্যই হবে, এলএস আউটপুট পার্সিংয়ের দরকার নেই, খালি আছে কিনা তা দেখুন। ফাইন্ড ব্যবহার করে আমার কাছে কেবল ওভারকিলের মতো মনে হয়।
akostadinov

4

এটি বর্তমান কার্যকারী ডিরেক্টরিতে (।) কাজ করবে:

[ `ls -1A . | wc -l` -eq 0 ] && echo "Current dir is empty." || echo "Current dir has files (or hidden files) in it."

বা একই কমান্ডটি আরও পঠনযোগ্য হওয়ার জন্য তিনটি লাইনে বিভক্ত:

[ `ls -1A . | wc -l` -eq 0 ] && \
echo "Current dir is empty." || \
echo "Current dir has files (or hidden files) in it."

আপনার যদি এটি অন্য কোনও লক্ষ্য ফোল্ডারে চালানো দরকার হয় তবে তার ls -1A . | wc -lসাথে প্রতিস্থাপন ls -1A <target-directory> | wc -lকরুন।

সম্পাদনা করুন : আমি প্রতিস্থাপন -1aকরেছি -1A(@ ড্যানিয়েল মন্তব্য দেখুন)


2
ls -Aপরিবর্তে ব্যবহার করুন। কিছু ফাইল সিস্টেমে ডক্স অনুসারে .এবং ..প্রতীকী লিঙ্ক নেই।
ড্যানিয়েল বেক

1
ধন্যবাদ @ ড্যানিয়েল, আপনার পরামর্শের পরে আমি আমার উত্তর সম্পাদনা করেছি। আমি জানি "1" সম্ভবত মুছে ফেলা হবে।
ztank1013

2
এটি ক্ষতি করে না, তবে এটি যদি বোঝায় যে এটি যদি টার্মিনালে আউটপুট না করে। যেহেতু আপনি এটি অন্য প্রোগ্রামে পাইপ করেছেন, তাই এটি অনর্থক।
ড্যানিয়েল বেক

-1অবশ্যই নিরর্থক। এমনকি lsযখন পাইপ দেওয়া হবে তখন প্রতি লাইনে একটি আইটেম মুদ্রণ না করে তবে এটি শূন্য বা তার বেশি লাইন তৈরি করেছে কিনা তা যাচাই করার ধারণাকে প্রভাবিত করে না।
ভিক্টর ইয়ারেমা

3

নিম্নলিখিত ব্যবহার:

count="$( find /path -mindepth 1 -maxdepth 1 | wc -l )"
if [ $count -eq 0 ] ; then
   echo "No new file"
   exit 1
fi

এইভাবে, আপনি এর আউটপুট ফর্ম্যাট থেকে স্বতন্ত্র ls-mindepthডিরেক্টরি নিজেই এড়িয়ে যায়, -maxdepthজিনিসগুলিকে গতি বাড়ানোর জন্য বার বার সাব-ডাইরেক্টরিগুলিতে রক্ষা করতে বাধা দেয়।


অবশ্যই, আপনি এখন নির্ভর করে wc -lএবং findআউটপুট ফর্ম্যাটটিতে (যা যুক্তিসঙ্গতভাবে পরিষ্কার)।
ড্যানিয়েল বেক

3

একটি অ্যারে ব্যবহার:

files=( * .* )
if (( ${#files[@]} == 2 )); then
    # contents of files array is (. ..)
    echo dir is empty
fi

3
খুব সুন্দর সমাধান, তবে নোট করুন যে এটির দরকারshopt -s nullglob
xebeche

3
${#files[@]} == 2ধৃষ্টতা রুট Dir জন্য দাঁড়ানো না (আপনি সম্ভবত যদি এটা খালি কিন্তু পরীক্ষা করা হবে না কিছু কোড যে সীমাবদ্ধতা করতে পারি সে সম্পর্কে জানে না)।
আইভান_পোজদেদেব

3

একটি হ্যাকি, তবে কেবল ব্যাশ-মুক্ত, পিআইডি-মুক্ত উপায়:

is_empty() {
    test -e "$1/"* 2>/dev/null
    case $? in
        1)   return 0 ;;
        *)   return 1 ;;
    esac
}

এটি এই সিদ্ধান্তটি গ্রহণ করে যে testবিল্টিন 2 দিয়ে প্রস্থান করে যদি একাধিক যুক্তি দেওয়া হয় -e: প্রথমে, "$1"/*গ্লোব বাশ দ্বারা প্রসারিত হয়। এটি প্রতি ফাইলের জন্য একটি যুক্তিতে ফলাফল দেয়। সুতরাং

  • যদি কোনও ফাইল না থাকে, তারের অরক্ষেত্রটি test -e "$1"*প্রসারিত হয় না, তাই শেল নামকরণের চেষ্টা করা ফাইলটিতে ফিরে যায় *, যা 1 প্রদান করে।

  • ... কেবলমাত্র যদি সেখানে কোনও ফাইলের নাম দেওয়া হয় ঠিক *ততক্ষনে, তারপুস্তকটি প্রসারিত হয়, নক্ষত্রটি, যা উপরের মত একই কল হিসাবে শেষ হয়, অর্থাৎ। test -e "dir/*", ঠিক এই মুহূর্তে 0 ফিরে আসে। (এটি নির্দেশ করার জন্য ধন্যবাদ @ ট্রুইয়।)

  • যদি একটি ফাইল থাকে, test -e "dir/file"চালানো হয়, যা 0 প্রদান করে।

  • তবে যদি 1 এর বেশি ফাইল থাকে test -e "dir/file1" "dir/file2" তবে চালানো হয়, যা ব্যাশ এটি ব্যবহারের ত্রুটি হিসাবে অর্থাৎ 2 হিসাবে রিপোর্ট করে।

case পুরো লজিককে এমনভাবে আবৃত করে যাতে 1 প্রস্থান স্থিতি সহ প্রথম প্রথম কেস সাফল্যের হিসাবে রিপোর্ট করা হয়।

সম্ভাব্য সমস্যাগুলি আমি যাচাই করি নি:

  • অনুমোদিত আর্গুমেন্টের সংখ্যার চেয়েও বেশি ফাইল রয়েছে - আমার ধারণা এটি 2+ ফাইলের সাথে সাদৃশ্যপূর্ণ আচরণ করতে পারে।

  • বা একটি খালি নাম সহ আসলে ফাইল আছে - আমি নিশ্চিত না যে এটি কোনও বুদ্ধিমান ওএস / এফএসে সম্ভব।


1
গৌণ সংশোধন: দির / তে কোনও ফাইল না থাকলে test -e dir/*তাকে ডাকা হয়। যদি একমাত্র ফাইলটি '*' দির হয় তবে পরীক্ষাটি 0 ফিরে আসবে যদি আরও ফাইল থাকে তবে এটি 2 ফিরে আসে returns সুতরাং এটি বর্ণিত হিসাবে কাজ করে।
সত্য

আপনি ঠিক বলেছেন, @ ট্রুই, আমি এটি উত্তরে অন্তর্ভুক্ত করেছি। ধন্যবাদ!
অ্যালোস মাহডাল

2

FIND (1) দিয়ে (লিনাক্স এবং ফ্রিবিএসডি এর অধীনে) আপনি "-maxdepth 0" এর মাধ্যমে ডিরেক্টরি এন্ট্রিটিতে পুনরাবৃত্তভাবে দেখতে পারেন এবং "-mpty" দিয়ে ফাঁকা থাকলে পরীক্ষা করতে পারেন। এই প্রশ্নটি প্রয়োগ করে:

if test -n "$(find ./ -maxdepth 0 -empty)" ; then
    echo "No new file"
    exit 1
fi

এটি 100% পোর্টেবল নাও হতে পারে তবে এটি মার্জিত।
ক্রেগ রিঞ্জার

1

আমি মনে করি সেরা সমাধানটি হ'ল:

files=$(shopt -s nullglob; shopt -s dotglob; echo /MYPATH/*)
[[ "$files" ]] || echo "dir empty" 

ধন্যবাদ https://stackoverflow.com/a/91558/520567

এটি আমার উত্তরের একটি বেনামী সম্পাদনা যা কারও পক্ষে সহায়ক হতে পারে বা নাও হতে পারে: সামান্য পরিবর্তন ফাইলের সংখ্যা দেয়:

files=$(shopt -s nullglob dotglob; s=(MYPATH/*); echo ${s[*]}) 
echo "MYPATH contains $files files"

ফাইলনেমে ফাঁক থাকলেও এটি সঠিকভাবে কাজ করবে।


1
if find "${DIR}" -prune ! -empty -exit 1; then
    echo Empty
else
    echo Not Empty
fi

সম্পাদনা করুন: আমি মনে করি যে এই সমাধান GNU খোঁজ সঙ্গে কাজ করে জরিমানা, একটি পর দ্রুত এ বর্ণন বাস্তবায়ন । তবে এটি কাজ করে না, উদাহরণস্বরূপ, নেটবিএসডি এর অনুসন্ধান । প্রকৃতপক্ষে, এটি স্ট্যাট (2) এর st_size ক্ষেত্র ব্যবহার করে। ম্যানুয়ালটি এটিকে বর্ণনা করে:

st_size            The size of the file in bytes.  The meaning of the size
                   reported for a directory is file system dependent.
                   Some file systems (e.g. FFS) return the total size used
                   for the directory metadata, possibly including free
                   slots; others (notably ZFS) return the number of
                   entries in the directory.  Some may also return other
                   things or always report zero.

আরও সহজ সমাধান, আরও সহজ, হ'ল:

if find "${DIR}" -mindepth 1 -exit 1; then
    echo Empty
else
    echo Not Empty
fi

এছাড়াও, 1 ম সমাধানে প্রিনটি অকেজো।

সম্পাদনা: Gnu সন্ধানের জন্য কোন প্রস্থান ছাড়ুন .. উপরের সমাধানটি নেটবিএসডি-র সন্ধানের জন্য ভাল। জিএনইউ অনুসন্ধানের জন্য, এটি কাজ করা উচিত:

if [ -z "`find \"${DIR}\" -mindepth 1 -exec echo notempty \; -quit`" ]; then
    echo Empty
else
    echo Not Empty
fi

এটি থেকে গনুহ findutils 4.6.0 (সর্বশেষ সংস্করণ) একটি নেই -exitসম্পৃক্ত
ডেনিস

0

এটি সমস্ত দুর্দান্ত জিনিস - স্রেফ এটিকে একটি স্ক্রিপ্ট বানিয়েছি যাতে আমি বর্তমানের নীচে খালি ডিরেক্টরিগুলি পরীক্ষা করতে পারি। নীচে 'ফাইন্ডেম্টি' নামে একটি ফাইল স্থাপন করা উচিত, যে কোনও জায়গায় রেখে দেওয়া হয়েছে যাতে বাশ এটি খুঁজে পেতে পারে এবং chmod 755 চালাতে পারে। আমি অনুমান করি যে আপনার নির্দিষ্ট প্রয়োজনগুলিতে সহজেই সংশোধন করা যায়।

#!/bin/bash
if [ "$#" == "0" ]; then 
find . -maxdepth 1 -type d -exec findempty "{}"  \;
exit
fi

COUNT=`ls -1A "$*" | wc -l`
if [ "$COUNT" == "0" ]; then 
echo "$* : $COUNT"
fi

0

../INস্ক্রিপ্ট ডিরেক্টরিতে বিবেচনা করে ডিরেক্টরিতে ফাইলগুলি পরীক্ষা করা ও প্রক্রিয়া করা, আমার জন্য এটি কাজ করে ../Script:

FileTotalCount=0

    for file in ../IN/*; do
    FileTotalCount=`expr $FileTotalCount + 1`
done

if test "$file" = "../IN/*"
then

    echo "EXITING: NO files available for processing in ../IN directory. "
    exit

else

  echo "Starting Process: Found ""$FileTotalCount"" files in ../IN directory for processing."

# Rest of the Code

0

ডিরেক্টরি উপস্থিত থাকলে টেস্টিং সম্পর্কে এবং স্টেটমেন্টের একটিতে খালি না হলে about

if [[ -d path/to/dir && -n "$(ls -A path/to/dir)" ]]; then 
  echo "directory exists"
else
  echo "directory doesn't exist"
fi

-1

বর্তমানের ডিরেক্টরি বাদে অন্য যে কোনও ডিরেক্টরিতে এটি চেষ্টা করে খালি কিনা তা পরীক্ষা করে দেখতে পারেন rmdir, কারণ rmdirখালি নয় এমন ডিরেক্টরিতে ব্যর্থ হওয়ার নিশ্চয়তা রয়েছে। যদি rmdirসফল হয় এবং আপনি খালি ডিরেক্টরিটি পরীক্ষা থেকে বাঁচতে চেয়েছিলেন তবে mkdirএটি কেবল ।

এই হ্যাকটি ব্যবহার করবেন না যদি এমন অন্যান্য প্রক্রিয়া রয়েছে যা সংক্ষেপে অস্তিত্ব রুদ্ধ করতে পারে এমন একটি ডিরেক্টরি দ্বারা বিভাজন হয়ে উঠতে পারে।

যদি আপনার rmdirপক্ষে কাজ না করে এবং আপনি সম্ভবত ডিরেক্টরিগুলি পরীক্ষা করতে পারেন যেগুলি সম্ভাব্য সংখ্যক ফাইল থাকতে পারে, শেল গ্লোব্বিংয়ের উপর নির্ভর করে যে কোনও সমাধান ধীর হয়ে যায় এবং / অথবা কমান্ড লাইনের দৈর্ঘ্যের সীমাতে চলে যেতে পারে। সেক্ষেত্রে সম্ভবত ব্যবহার করা ভাল findfindআমি ভাবতে পারি দ্রুততম সমাধানটি এর মত যায়

is_empty() {
    test -z $(find "$1" -mindepth 1 -printf X -quit)
}

এটি জিএনইউ এবং বিএসডি সংস্করণগুলির জন্য কাজ করে findতবে সোলারিসের জন্য নয়, যা এই findঅপারেটরগুলির প্রত্যেককেই অনুপস্থিত । আপনার কাজ ভালবাসুন, ওরাকল।


ভালো বুদ্ধি নই. ডিরেক্টরিটি খালি ছিল কিনা তা ওপি কেবল পরীক্ষা করতে চেয়েছিল।
রোয়াইমা

-3

আপনি ডিরেক্টরিটি মুছে ফেলার চেষ্টা করতে পারেন এবং একটি ত্রুটির জন্য অপেক্ষা করতে পারেন; rmdir ডিরেক্টরিটি খালি না হলে মুছবে না।

_path="some/path"
if rmdir $_path >/dev/null 2>&1; then
   mkdir $_path        # create it again
   echo "Empty"
else
   echo "Not empty or doesn't exist"
fi

3
-1 এটি এমন ধরণের কোড যা ব্যাকফায়ার করে। rmdirআমার যদি ডিরেক্টরি সরানোর অনুমতি না দেয় তবে ব্যর্থ হবে; বা যদি এটি একটি বিটিআরএফএস সাবভলিউম হয়; বা যদি এটি কেবল পঠনযোগ্য ফাইল সিস্টেমের অন্তর্ভুক্ত। এবং যদি rmdirব্যর্থ হয় না এবং mkdirচালিত হয়: যদি ইতিমধ্যে সরানো ডিরেক্টরিটি অন্য ব্যবহারকারীর হয়? এর (সম্ভবত অ-মানক) অনুমতিগুলি সম্পর্কে কী বলা যায়? ACL এর? বর্ধিত গুণাবলী? সব হারিয়ে গেছে।
কামিল ম্যাকিয়েরোস্কি

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