খালি স্ট্রিং -d ব্যবহার করে কোনও ফোল্ডার উপস্থিত রয়েছে কিনা তা কেন সত্য?


8

আমি কিছু স্ক্রিপ্ট লিখছিলাম এবং এরকম কিছু লিখেছিলাম

ARTIFACTS="/SOME/PATH"
[ -d $ARTIFCATS ] && rm -rf $ARTIFACTS/*

যা ঘটেছিল তা হল নির্বুদ্ধিতার বাইরে আমি প্রথমটি কার্যকর না করেই দ্বিতীয় লাইনটি কার্যকর করেছিলাম। দেখা গেল যে [-d ""] সত্য ফিরে আসে এবং এক্সপ্রেশন হয়ে যায়

rm -rf /*

ভাগ্যক্রমে এটি কেবল একটি পরীক্ষা মেশিন ছিল এবং আমি একটি সুডো ছিলাম না, তবে আমি কিছু তথ্য হারিয়েছি

আমার প্রশ্ন, কেন [-d ""] সত্য ফিরে আসে ?? ডকুমেন্টেশনে স্পষ্টভাবে বলা হয়েছে যে এটি কোনও পাথ বিদ্যমান এবং এটি একটি ফোল্ডার কিনা তা যাচাই করে

আমি ব্যবহার করে সমস্যাটি সমাধান করেছি

[ -e $ARTIFACTS ]
যা দেখে মনে হচ্ছে

চিয়ার্স


5
অথবা আপনি উভয় লাইন কার্যকর করেছেন। উপরের কোড উদাহরণে আপনি কখনই আরটিআইফিস্যাটস সেট করেন নি।
বুহব

2
আমি শুধু যে লিখতে হবে rm -rf $ARTIFACTSছাড়া /*। এটি $ARTIFACTSডিরেক্টরিটি মুছে ফেলবে , যা ভাল, কারণ যদি আমি নিশ্চিত হতে চাই যে এটিতে কিছু রাখার আগে এটি বিদ্যমান আছে তবে আমি mkdir -p $ARTIFACTSযেভাবেই চালিয়ে দেব । এছাড়া ভিতরে লুকানো মুছে ফেলবে ফাইল $ARTIFACTS, যা জরিমানা, কারণ আমি না লিখতে হবে rm -rf $ARTIFACTS/*যদি $ARTIFACTSঅন্তর্ভুক্ত কিছু আমি রক্ষা করতে চেয়েছিলেন।
ক্রিস্টোফার হামারস্ট্রিম

@ ক্রিস্টোফারহ্যামারস্ট্রিম খুব সত্য
মোয়াতাজ এলমাস্রি

উত্তর:


9

1. এই দুটি পরীক্ষা সত্য ফিরে :

# [ -d ] && echo true || echo false
true
# [ -d $SOME_UNSET_VAR ] && echo true || echo false
true

পসিক্স অনুসারে (@ টিম ব্যাখ্যা করেছেন)।

২. তবে এটি মিথ্যা প্রত্যাবর্তন করে ( প্রশ্নে বর্ণিত সত্য নয় )

# [ -d "" ] && echo true || echo false
false

কারণ testদুটি আর্গুমেন্ট সহ বলা হয় (যদিও দ্বিতীয়টি খালি স্ট্রিং)।

৩. এজন্য ( ) [[ … ]]পরিবর্তে ব্যবহার করা ভাল অনুশীলন , যা সর্বাধিক (সমস্ত?) শেল সরবরাহ করে। আপনি পর্যাপ্ত আর্গুমেন্ট সরবরাহ করেন কিনা তা এই চেকগুলি নির্মাণ করে (অন্যথায় একটি ত্রুটি নিক্ষেপ করে এবং বাতিল করা হয়)test[ … ]

# [[ -d ]] && echo true || echo false
bash: unexpected argument `]]' to conditional unary operator
bash: syntax error near `]]'

বা কেবল এমনভাবে আচরণ করে যেমন একজন প্রত্যাশা করবে:

# [[ -d $SOME_UNSET_VAR ]] && echo true || echo false
false

৪. এবং, @ গিলস দ্বারা চিহ্নিত হিসাবে, আরও গুরুত্বপূর্ণ হল উদ্ধৃতি বিকল্পগুলি দ্বিগুণ করা। সুতরাং -d "$SOME_UNSET_VAR"প্রসারিত হয় -d ""এবং এমনকি মিথ্যা প্রদান করে test(কেস 2 এর সমান)। সুতরাং এটি বোর্ন শেলের সাথেও সামঞ্জস্যপূর্ণ sh:

# [ -d "$SOME_UNSET_VAR" ] && echo true || echo false
false

3.00.16 (1) এবং 4.1.5 (1) এর সাথে পরীক্ষিত


1
বাশ, ksh এবং zsh সরবরাহ করে [[ … ]]তবে সহজ নয় sh। সত্যিই গুরুত্বপূর্ণ অনুশীলন হয় কমান্ড বদল প্রায় ডবল কোট করা : [ -d "$ARTIFACTS" ]
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

6

এই প্রশ্নের উত্তর ইতিমধ্যে স্ট্যাকওভারফ্লোতে দেওয়া হয়েছে। এটি বলে যে পসিক্স মান অনুসারে testসর্বদা সফল হওয়া উচিত যদি একে একে একে একটি খালি খালি যুক্তি (এবং অন্য কোনও যুক্তি) না দিয়ে ডাকা হয়।

এটির ক্ষেত্রেও এটি হওয়া উচিত test -e(এবং বাস্তবে এটি আমার সিস্টেমে রয়েছে), তাই সাবধান হন।

পরিবর্তে ব্যবহার করুন:

[ -d "$ARTIFACTS" ]

test এরপরে ভেরিয়েবলটি খালি থাকলেও দুটি আর্গুমেন্টের সাথে ডাকা হবে এবং এক্ষেত্রে ভুয়া ফিরবে।


"ঠিক এক অসাধারণ যুক্তি।" - এটি একটি বিভ্রান্তিমূলক সংক্ষিপ্তসার - আপনি যে পৃষ্ঠাটি লিঙ্ক করেছেন তাতে ঠিক একটি যুক্তির সাথে ডাকা হচ্ছে এবং সেই যুক্তিটি খালি নয় বলে উল্লেখ করা হয়েছে; খালি যুক্তি দিয়ে কোনও অযৌক্তিক যুক্তির মামলা সম্পর্কে কিছুই নেই। সঠিক সমাধানটি উদ্ধৃতিতে চলক নামটি ঘিরে থাকা উচিত।
র্যান্ডম 832

@ র্যান্ডম 832 আপনাকে ধন্যবাদ! আমি আপনার প্রস্তাবিত দুটি পরিবর্তনই প্রয়োগ করেছি।
টিম

[ ! -z $ARTIFACTS ] && [ -d $ARTIFACTS ]এর চেয়ে ভাল আর নয়: $ARTIFACTSখালি থাকলে এটি কেবলমাত্র বিশেষ ক্ষেত্রে পূরণ করে তবে $ARTIFACTSহোয়াইটস্পেস বা থাকতে পারে এমন ক্ষেত্রে ব্যর্থ হয় \[?*[ -d "$ARTIFACTS" ]এটি করার সঠিক উপায় (বা [[ -d $ARTIFACTS ]]যে শেলগুলিতে রয়েছে [[ … ]])।
গিলস 'অশুভ হওয়া বন্ধ করুন'

@ গিলস আপনি ঠিক বলেছেন, আমি এটি সরিয়েছি han ধন্যবাদ!
টিম

4

আমি [-e $ ARTIFACTS] ব্যবহার করে সমস্যার সমাধান করেছি যা মনে হচ্ছে কাজ করছে

আপনি ভুল । এটি কাজ করে কারণ $ARTIFACTSএখন কিছু সেট করা আছে।

যখন কোনও ভেরিয়েবল সেট করা থাকে না, তারপরে বলছি

[ -d $SOMEVAR ]

অথবা

[ -e $SOMEVAR ]

হবে উভয় মূল্যায়ন trueকরা হয়েছে কারণ এটি বলার অপেক্ষা রাখে না বোঝা

[ -d ]

এবং

[ -e ]

যথাক্রমে। (বলা [ foobar ]সর্বদা সত্যকে মূল্যায়ন করবে))

উক্তি

set -u

এই ধরনের পরিস্থিতিতে কাজে আসে। help setআপনাকে বলতে হবে:

  -u  Treat unset variables as an error when substituting.

[-e ""] && প্রতিধ্বনি "কিছু কিছু" প্রিন্ট করে না, তবে কীভাবে ভুল হতে পারে?
মোয়াতাজ এলমাস্রি

2
Ahh খালি নিদর্শন উৎপাদনের [-e] না [-e ""], বুঝেছি সঙ্গে বিষ্ঠা [-e $ নিদর্শন]
Moataz Elmasry

4

দেখুন যে আপনি ভেরিয়েবল আর্টিফ্যাক্টস সেট করেছেন এবং আপনি আরটিআইএফআইএফটিএসের জন্য পরীক্ষা করছেন। সম্ভবত ভুল টাইপিং?

যাইহোক, -d পাশাপাশি -e আনসেট ভেরিয়েবলগুলিতে একই ফলাফল উত্পন্ন করবে।

সুতরাং ডাবল উদ্ধৃতি ব্যবহার করুন এবং এটি আপনাকে সাহায্য করবে।

ARTIFACTS="/SOME/PATH"
[ -d "$ARTIFACTS" ] && rm -rf -- "$ARTIFACTS/"*

দ্রষ্টব্য: আপনার "/ Some / PATH" এর সাথে যদি স্থান সহ কোনও ফোল্ডার থাকে তবে আপনার উল্লিখিত স্ক্রিপ্টটি "বাইনারি অপারেটর প্রত্যাশিত" ত্রুটির সাথে ভেঙে যাবে।

উদাহরণ:

ARTIFACTS="/home backup/"

1) [ -d $ARTIFACTS ] && rm -rf $ARTIFACTS/*
bash: [: /home: binary operator expected

2) [ -d "$ARTIFACTS" ] && rm -rf "$ARTIFACTS"/*

জরিমানা করবে rmঅনুরোধে উদ্ধৃতিগুলিও ভুলে যাবেন না (উপস্থিত rm -rf $ARTIFACTSথাকবেন না এমন /homeঅভিযোগে উত্সাহিত করে মুছে ফেলবেন backup/*)।

এছাড়াও, -Lচেক সহ এটি নিশ্চিত করবে যে এটি একটি ডিরেক্টরি এবং কেবল একটি ডিরেক্টরিতে প্রতীকী লিঙ্ক নয়।

সুতরাং, মূলত,

[ -d "$ARTIFACTS" && ! -L "$ARTIFACTS" ] && rm -rf -- "$ARTIFACTS"/*
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.